2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3  След.
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 12:34 


24/05/09

2054
Если X и Y взаимоисключающие, т.е. не может быть 0,0 и 1,1, то:

Код:
А
if(X) {B}
else {C}


Если В и С большие участки кода, то просто в фигурные скобочки их. Не надо вызывать функции. Не надо проверять Y.

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 13:47 
Аватара пользователя


28/01/12
467
Alexu007 в сообщении #824847 писал(а):
Если X и Y взаимоисключающие, т.е. не может быть 0,0 и 1,1
Да в том-то и дело, что ТС задаёт их как:
Цитата:
"Есть 2 несовместных условия (X и Y)"
т.е. возможен случай 0,0. А вот 1,1 - исключён.

Alexu007 в сообщении #824847 писал(а):
Не надо проверять Y.
Выходит надо.

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 14:49 


24/05/09

2054
Код:
if(X) {А; B;}
else if (Y) {A; C;}

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 15:11 


07/01/14
7
Выполнить блок А
Если условие Х истинно, выполнить блок B
Если условие Y истинно, выполнить блок C

Порядок строк неважен.

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 15:45 
Заслуженный участник
Аватара пользователя


28/07/09
1238
_Ivana
_Ivana в сообщении #824721 писал(а):
Приведите пример на другом, нелюбимом вами языке, в котором эта простая вещь делается красиво. Чтобы было видно, что вы хотите.
Я привёл пример на "C c GOTO". Могу также на ассемблере привести, но это будет просто "развёрнутое" то же самое. Задача - как-нибудь красиво написать программу на "C без GOTO" так, чтобы полученный код не делал никаких "лишних действий", про сравнению с.
Это довольно мутная просьба, я знаю.
_Ivana в сообщении #824721 писал(а):
А вот что вы хотите - визуальную красоту кода на языке высокого уровня или его оптимальность, вы и скажите.
Красоту.

(Странная фантазия про гипотетический оператор)

Ну например! Как это можно было бы сделать.
Многие знают про сокращённый тернарный оператор. Он есть и в C. Я уже и с ним пытался сделать, но выходит всё равно криво.
Как работает этот оператор, вы можете прочитать по ссылке.

Итак. Ввожу новый оператор "⸮:"
Его действие:
y ⸮: x (буквы переставлены не случайно).
Проверяет на nonzero x
Если не 0, то выполняет y, а возвращает x
Если 0, возвращает 0

Этот оператор является помесью сокращенного тернарного оператор и оператора запятой
Реализовать такое же действие можно например так X?(Y,X):0
  1. #include <stdio.h> 
  2. #define NewOp(X,Y) X?(Y,X):0  
  3. main() 
  4. int n, stat; 
  5. while(1) 
  6. scanf("%d", &n); 
  7. stat=NewOp(n>0, printf("positive")); 
  8. printf("\n%d\n", stat); 
Можете убедиться, что оператор работает. Правда, пришлось обойтись без красивого значка ⸮

Вот, с помощью подобной конструкции, можно легко и изящно реализовывать всякие сложные ветвления.
В том числе наш случай:
  1. if( (X⸮:B) || (Y⸮:C) ) A; 
NT2000
NT2000 в сообщении #824740 писал(а):
Вот конструкция:
if( x?B():( y?C(): false))
{ A(); }

Такая конструкция подходит, только ещё нужно учесть, что B и C могут 0 вернуть. Нужно так if( X? (B, true): Y? (C, true): false) A;
Здесь запятая - это оператор запятая.


Но пока меня эти кунштюки не вдохновили. Видимо, идеально подходящей конструкции для данного случая, в языке C просто нет, раз уже столько участников высказалось.

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 16:03 
Аватара пользователя


28/01/12
467
А это?
Код:
...
if( x ) B;
else if( y ) C;
else return 0;
A;
return 0;

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 16:38 
Заслуженный участник


09/09/10
3729
Чем плохо
Код:
void A() { ... }
void B() { ... }
void C() { ... }

...
int x = X;
int y = Y;

A();
if (x) { B(); }
if (y) { C(); }


?

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 17:51 


24/05/09

2054
Говорят, возможен случай X=0, Y=0, тогда ничего не выполняется?

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 19:32 
Заслуженный участник


27/04/09
28128
Да, тогда ничего.

Alexu007 в сообщении #824847 писал(а):
X и Y взаимоисключающие, т.е. не может быть 0,0
Не т. е.. «Взаимоисключающие» никогда не означало, что условия не могут быть оба ложными.

Legioner93 в сообщении #824890 писал(а):
Такая конструкция подходит, только ещё нужно учесть, что B и C могут 0 вернуть. Нужно так
if( X? (B, true): Y? (C, true): false) A;
Здесь запятая - это оператор запятая.
…и получается прекрасный write-only код! :appl:

В общем, флаги и выделение A, B, C в функции для отделения от логики — это было бы нормально. Ну уж флагов точно нечего стыдиться, согласен с высказавшими это на всю 1.

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 19:57 
Заслуженный участник


09/09/10
3729
Alexu007 в сообщении #824941 писал(а):
Говорят, возможен случай X=0, Y=0, тогда ничего не выполняется?

Если нужно именно такое поведение, то
Код:
if (x || y) { A(); }
if (x) { B(); }
if (y) { C(); }


-- Пн фев 10, 2014 20:58:41 --

И пускай там уже компилятор играет с регистрами и инлайнит функции, все равно у него это выходит куда как лучше.

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 21:00 


05/09/12
2587
Legioner93, ваш посыл понятен. И компьютер все стерпит. Но мне, надеюсь, не придется разбираться в вашем коде.
А что касается реализации сложных ветвлений, я стараюсь писать максимально прозрачно и понятно, при этом формируя конструкцию так, чтобы долгие и сложные условия вычислялись только когда они необходимы, а не каждый раз, когда по другим условиям уже понятно, что эта ветка алгоритма не выполнится в данном случае.

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 22:36 
Заслуженный участник
Аватара пользователя


28/07/09
1238
NT2000
NT2000 в сообщении #824898 писал(а):
А это?
Код:
...
if( x ) B;
else if( y ) C;
else return 0;
A;
return 0;

Правильно ли я понял, что весь "остальной" код программы нужно засунуть во второй "else"? Со множественными return пока не работал.
arseniiv
arseniiv в сообщении #824980 писал(а):
Legioner93 в сообщении #824890 писал(а):
Такая конструкция подходит, только ещё нужно учесть, что B и C могут 0 вернуть. Нужно так
if( X? (B, true): Y? (C, true): false) A;
Здесь запятая - это оператор запятая.
…и получается прекрасный write-only код! :appl:

Спасибо :D
Я не спорю, что подобные конструкции вредны. По мне уж лучше прозрачный и эффективный goto, снабженный комментариями к неочевидным местам. И это было только исправление кода NT2000, кстати.
Насчёт макросов, которые вы вчера предлагали - я написал один в предыдущем своём сообщении, посмотрите. Как считаете, такие штуки применимы на практике, если подобные ситуации возникают в коде много-много раз?
_Ivana
Пока я ещё никакого настоящего кода не пишу, так, балуюсь. Но скоро планирую, да.
На мой взгляд, подобные выдуманные упражнения не вредны для самостоятельной работы. Я же не говорил, что всякие эти извращения буду использовать на людях :P

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение10.02.2014, 23:18 
Заслуженный участник


27/04/09
28128
Legioner93 в сообщении #825071 писал(а):
Насчёт макросов, которые вы вчера предлагали - я написал один в предыдущем своём сообщении, посмотрите. Как считаете, такие штуки применимы на практике, если подобные ситуации возникают в коде много-много раз?
Точно не в текущем виде. :-) Во-первых, обычно сразу при описании макросов замечают, что из-за чисто строковой замены препроцессором нужно ставить там некоторое количество скобок, чтобы ненароком макрос не развернулся в что-то неожиданное. С текущим определением #define NewOp(X,Y) X?(Y,X):0 штука вида NewOp(a,b)+1 развернётся в a?(a,b):0+1, и теперь вспомним приоритет +, который выше ?:.
Не знаю, как насчёт препроцессора в новом стандарте, а раньше приходилось окружать все аргументы и тело замены скобками: #define NewOp(X,Y) ((X)?((Y),(X)):0). Тогда уж никак компилятору не понять неправильно.

Ещё у макроса имя невыразительное. Ну да, ясно, что это пример. :-)
И ещё если нет никакого значимого улучшения производительности перед inline-функциями, надо использовать их, и аналогично с не-inline-функциями. (Эх, и снова не помню, появились ли inline в C.)

-- Вт фев 11, 2014 02:21:51 --

(Лучше не спрашивайте меня про C. Спрашивать про C# уже намного полезнее, ответы будут качественнее.)

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение11.02.2014, 00:15 
Аватара пользователя


28/01/12
467
Так вы только учите С?!
Мой вам совет - учите, но без этих всех выкрутасов.
Когда будите в основном знать язык - тогда и разные штучки начнёте применять.
А пока зачем забивать себе голову?

Там очень просто, в коде, где надо вам обслужить А В и С сделайте, так:
Код:
// декларация функции решающей проблемы с А,В,С
int A_B_C(){
if( x ) B;
else if( y ) C;
else return 0;
A;
return 0;
}

// ваша программа
{
...
// тут замозрочки с А,В и С
// сделайте вызов функции
A_B_C();
// тут продолжение вашей программы
...
}

 Профиль  
                  
 
 Re: Как обойтись без GOTO, но максимально красиво соблюсти D.R.Y
Сообщение11.02.2014, 00:45 
Заслуженный участник
Аватара пользователя


28/07/09
1238
NT2000
NT2000 в сообщении #825128 писал(а):
Так вы только учите С?!

Да. Но это не значит, что я не умею программировать.
NT2000 в сообщении #825128 писал(а):
Мой вам совет - учите, но без этих всех выкрутасов.

Не считаю такой подход эффективным.

По поводу вашего кода - он мне абсолютно понятен и прозрачен, просто с первого раза я не догадался, что вы предлагаете это вынести в отдельную функцию. Тупанул вот. Решил, что несколько return 0 - это какие-то непонятные мне махинации именно с main-овским return 0, для этого и уточнил.

arseniiv
Насчёт дополнительных скобок - спасибо за ценное замечание. Вроде и помнил об этом где-то "на фоне", а когда до практики дошло, забыл их написать вот (на самом деле просто редко использую пока подобного рода конструкции).

По-моему inline функций в C нет. Я знаю про эти штуки, хотя пока не применял.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 40 ]  На страницу Пред.  1, 2, 3  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group