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, Супермодераторы



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

Сейчас этот форум просматривают: Google [Bot]


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

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