Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Си
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2, 3, 4, 5, 6
igorle
Код в студию. Мы же программисты, и Си - наш язык.


Цитата(ARV @ Mar 20 2013, 17:26) *
возможно, я ваш код пойму с третьей минуты размышлений, а вы мой - с первой секунды, так чей же код будет лучше по критерию понимания? неужели ваша цель в том и состоит, чтобы таким, как я, осложнить жизнь? wink.gif

уверен, что после компиляции у нас обоих получится одно и то же в машинных кодах sm.gif

Компактный код - легче понять. Но этому надо научиться. Не зазорно не знать. Зазорно не желать знать.
Цель не усложнить жизнь, и уж тем более не унизить Вас.

Цель - заинтересовать Вас и тех, кто следит за этой веткой, узнать Си чуть поглубже. Прочуствовать его. Это как на машине. Сначала по прямой ехать трудно, а потом ты начинаешь чуствовать ее, и иногда можешь даже использовать занос с пользой. И начинаешь ездить свободно, и все внимание - только на дорожную ситуацию.

Если после нашей дискуссии вы перестаните писать слово профессионал в кавычках - значит мы не зря потратили время sm.gif
ARV
Цитата(Сергей Борщ @ Mar 20 2013, 17:26) *
Он уменьшил свое время на разбор этого куска кода в дальнейшем, в процессе сопровождения проекта. Эта конструкция охватывается взглядом целиком и моментально анализируется.
Сергей, при всем уважении: если бы он написал "проще" - время сопровождения ничуть не изменилось бы. в крайнем слчае на 1-2 секунды, что не может быть существенным. а вот вопрос-просьбу об указателях на функции вы пропустили... а ведь записанное в одну строку такое определение тоже охватывается взглядом сразу...
Цитата(Сергей Борщ @ Mar 20 2013, 17:26) *
Простите, это вы о чем
когда я писал ответ, в уме держал пример с & 0x3 - уже и без меня было показано, как эта константа связана с количеством символов в другой константе. это я и имел ввиду.

маловероятно, что symbols[byte & 0x0F] чем-то принципиально хуже того, что вы привели в качестве примера

Цитата(igorle @ Mar 20 2013, 17:37) *
профессионал в кавычках

я, как и вы, отлично понимаю контекст употребления слов профессионал и "профессионал" - если я написал слово в кавычках, я сделал это умышленно sm.gif смогу ли я назвать себя профессионалом, если перестану писать a = b ? 1 : 0, но стану a = !!b? или все-таки останусть "профессионалом"? wink.gif как по-вашему?

кстати, о вашем вопросе про ксор. с моей точки зрения мы снова попадаем в "лаконичность" Си: нет логических переменных, но есть логика отношений. соответственно, постоянно возникает проблма с пониманием, где переменная-число, а где переменная-логический_результат. на этом дуализме и построен ваш вопрос.

в вашем кратком стиле получится что-то типа
Код
a =(!b && c) || (!c && b)
.
ViKo
Цитата(igorle @ Mar 20 2013, 16:37) *
Код в студию. Мы же программисты, и Си - наш язык.

c = a && !b || !a && b;
igorle
Цитата(ViKo @ Mar 20 2013, 16:45) *
c = a && !b || !a && b;
Спасибо.

Теперь сравните с

c = !!a ^ !!b;

Допустим, мы разбираем чужой код. Понятно что ксор - не самоцель, а промежуточный результат. Может быть даже - аргумент функции. Какой вариант выберете теперь?
Кстати, это меня сын недавно научил, когда я вслух посетовал на то, что нету логического ксора. Сыну восемнадцать, но он уже профессионал. И такие конструкции для него - кирпичики. Он над ними не думает.
Повторюсь - это сродни английскому. Если ты его знаешь - ты думаешь "что написать". А если "со словарем" - то все силы уходят на "как правильно выразить мою, такую умную мысль"
ViKo
Цитата(igorle @ Mar 20 2013, 16:59) *
Теперь сравните с
c = !!a ^ !!b;
Какой вариант выберете теперь?

Я выберу ваш вариант! Спасибо. sm.gif
ARV
Цитата(igorle @ Mar 20 2013, 17:59) *
Теперь сравните с

c = !!a ^ !!b;
видите ли, если думать чуть дольше, чем достаточно, прийти к этому выражению не трудно. просто обычно нужды в этом не возникает - раз до цели дошли, и не устали, то дальше думать нет смысла. то есть либо кто-то (гуру) должен научить этому варианту, либо до него просторуки не дойдут. в первом случае я уже говорил о психологии, а во втором - выигрыш невелик.


почему мне больше нравится мой, неоптимальный, вариант? потому что его прочтение абсолютно непротивречиво: результат равен истине, если операнды логически разные - это видно по записи. а этот лаконичный вариант не так нагляден.


более того, с моей точки зрения этот выигрыш основан на еще одной "тонкости" Си, т.е. это просто какой-то хак в стандарте. если 25 == TRUE и !0 == TRUE, то математически вытекает, что 25 == !0. но тут мы попадаем на "нюансик": в Си оказывается, что !0 это 1, то есть 25 == 1!!!! то есть if(25 == 1) даст один эффект, но по этой логике эквивалентный if(25) - другой! в чем подвох?
долгое время я был уверен, что в Си логическая ИСТИНА, как значение выражения, соответствует ЛЮБОМУ НЕНУЛЕВОМУ значению. соответственно двойное отрицание приводит к неопределенности - очевидно это и послужило основанием сделать ИСТИНОЙ единицу, но оставить для совместимости и "иное ненулевое значение", что породило другую неопределенность... но ее назвали стандартом... назвать стандартом нелогичность - это разве плюс?
andrew_b
Цитата(ARV @ Mar 20 2013, 16:53) *
в Си есть ряд вещей, на которые никогда нельзя положиться, например, размерность int или знаковость char... я дословно стандарт не помню - написано там про это?
Си -- язык, близкий к платформе. некоторые называют его макроассемблером. Естественно, стандарт не может гарантировать размер char, если он разный на разных платформах. То, о чём вы пишете, в стандарте Си, естественно, написано. Но написано как implementation defined.
ARV
Цитата(andrew_b @ Mar 21 2013, 08:25) *
Си -- язык, близкий к платформе. некоторые называют его макроассемблером. Естественно, стандарт не может гарантировать размер char, если он разный на разных платформах. То, о чём вы пишете, в стандарте Си, естественно, написано. Но написано как implementation defined.
вообще-то вопрос был про то, написано ли в стандарте, что !0 == 1.
demiurg_spb
Цитата(igorle @ Mar 20 2013, 16:31) *
Все мы консервативны и держимся за свои привычки. Интересно наблюдать за человеком, который первый раз видит двойной восклицательный знак:
Код
int a, b;
a = 27;
b = !!a;
Многие сначала офигевают, и спорят, что это невозможно понять. А через время смотришь - сами так писать начинают. Привыкли.

Кстати, я проверял скомпилированный код для трех случаев:
Код
b = !!a;
b = a ? 1 : 0;
if (a)
    b = 1;
else
    b = 0;
Во всех трех случаях gcc дает одинаковый результат.

А я пишу иначе:
Код
b = (a!=0);


Цитата(ARV @ Mar 21 2013, 09:06) *
вообще-то вопрос был про то, написано ли в стандарте, что !0 == 1.
Что-то вас понесло...
ARV
Цитата(demiurg_spb @ Mar 21 2013, 09:41) *
Что-то вас понесло...

почему вы так считаете? мне идея сделать утверждение !0 равным 1 (напомню, читается это "НЕ НОЛЬ") не кажется идеальной, она противоречит логике, математике и вообще здравому смыслу: делать частный случай единственным решением - в корне неверно. более того, противоречит другому основополагающему принципу Си, а именно тому, что любое ненулевое число принимается за логическое значение ИСТИНА. и выражения !!а и т.п. по сути своей основаны на логическом противоречии. я со своей колокольни отношу это в раздел хаков, т.е. возможностей, которые вполне могли появиться в результате непреднамеренных действий. допустим, Керниган с Ритчи сначала не обратили внимание на эту несуразицу, а потом пришлось выдать это за "элегатную возможность", что и было стандартизировано. подобная ситуация уже давно практикуется в Windows: ошибки и баги майкрософт просто вводит в документированные возможности, делая их "официальными" sm.gif

или вы считаете, что противоречия тут нет?
demiurg_spb
Цитата(ARV @ Mar 21 2013, 11:16) *
Мне вам сказать нечего. Ваши фантазии не знают границ.
Не нравится !0 пишите ~0.
Я никаких противоречий в си стандарте не вижу.
Жалею лишь о том, что не реализован оператор сравнения (== !=) для структур, хотя присвоение допустимо...
ViKo
Цитата(ARV @ Mar 21 2013, 10:16) *
мне идея сделать утверждение !0 равным 1 (напомню, читается это "НЕ НОЛЬ") не кажется идеальной, она противоречит логике, математике и вообще здравому смыслу

Ну, почему же. Логике не противоречит. Ведь оператор ! - логический, выражение !0 дает логический результат, который представлен одним битом: Да/Нет, Правда/Ложь, 1/0.
XVR
Цитата(ARV @ Mar 21 2013, 09:06) *
вообще-то вопрос был про то, написано ли в стандарте, что !0 == 1.

А взять и посмотреть в стандарт религия не позволяет?

Цитата
6.5.3.3 Unary arithmetic operators
...
5 The result of the logical negation operator ! is 0 if the value of its operand compares
unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int.
The expression !E is equivalent to (0==E).
Так что !0 == 1
andrew_b
Цитата(ARV @ Mar 21 2013, 09:06) *
вообще-то вопрос был про то, написано ли в стандарте, что !0 == 1.
Написано.
ISO/IEC 9899:1999 (E), более нового под рукой нет:
Цитата
6.5.3.3 Unary arithmetic operators

5 The result of the logical negation operator ! is 0 if the value of its operand compares
unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int.
The expression !E is equivalent to (0==E).
ARV
Цитата(ViKo @ Mar 21 2013, 12:15) *
Ну, почему же. Логике не противоречит. Ведь оператор ! - логический, выражение !0 дает логический результат, который представлен одним битом: Да/Нет, Правда/Ложь, 1/0.
к сожалению, не могу с вами согласиться.

если бы в Си не было сказано, что любое ненулевое численное значение эквивалентно логической истине, противоречия действительно не было бы, а так есть вопрос:

Код
#define FALSE 0

#define TRUE !FALSE

int a = 25;


почему (a == TRUE) не эквивалентно (a != 0) ????

XVR
Цитата(ARV @ Mar 21 2013, 17:13) *
к сожалению, не могу с вами согласиться.

если бы в Си не было сказано, что любое ненулевое численное значение эквивалентно логической истине, противоречия действительно не было бы
А в C этого и не сказано. В С во всех местах, где используется логическое значение (в логических выражениях и операторах) сказано, что только они (а не все подряд) трактуют 0 как ложь и всё остальное, как истину.
Пример -
Цитата
6.5.13 Logical AND operator
Syntax
1 logical-AND-expression:
inclusive-OR-expression
logical-AND-expression && inclusive-OR-expression
Constraints
2 Each of the operands shall have scalar type.
Semantics
3 The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it
yields 0. The result has type int.


Цитата
6.8.4.1 The if statement
Constraints
1 The controlling expression of an if statement shall have scalar type.
Semantics
2 In both forms, the first substatement is executed if the expression compares unequal to 0.
In the else form, the second substatement is executed if the expression compares equal to 0. If the first substatement is reached via a label, the second substatement is not
executed.

и т.д.

Цитата
а так есть вопрос:

#define FALSE 0
#define TRUE !FALSE
int a = 25;

почему (a == TRUE) не эквивалентно (a != 0) ????
Потому что операция '==' не является условной операцией, и она не трактует свои аргументы как логические.

И отдельного типа bool в С нет (точнее там теперь есть _Bool, но это скорее недоразумение, чем полноценный bool rolleyes.gif )
ARV
Цитата(XVR @ Mar 21 2013, 18:21) *
Потому что операция '==' не является условной операцией, и она не трактует свои аргументы как логические.
вы даже не желаете быть внимательным...

разберем все по-порядку.


1. (a == TRUE) полностью эквивалентно (a == !0). читается это как "а эквивалентно не нулю" - это логическое утверждение, при а=25 оно истинно. я нигде не ошибся? однако, в Си ответ будет прямо противоположный!

2. (a != 0) читается как "а не равно нулю?" - это точно такое же логическое утверждение, и оно так же истинно при а=25. и в Си оно так же истинно.

3. с точки зрения логики оба примера абсолютно эквивалентны, так как "не равно нулю" это то же самое, что "равно чему угодно, кроме нуля"! однако, благодаря "изюминке" Си обычная математическая (и всякая другая ЛОГИКА) тут бессильна - в Си первое высказывание вопреки логике ЛОЖНО.

4. я придерживаюсь той точки зрения, что не смотря на то, что это нарушение логики возведено в стандарт, есть простой способ привести все в соответствии с логикой: надо ЗАБЫТЬ про то, что "не ноль" это 1 (т.е. !0 == 1), и понимать это именно так, как логическое высказывание понимает дисциплина "математическая логика", т.е. "не ноль" - это на самом деле любое число, кроме нуля (не Вася - это не только Петя, но и даже Лена). это соответствует всем канонам Си (пример - if(a)), и не противоречит здравому смыслу, в результате работы компилятора будет генерироваться то же самое. то есть я предлагаю не использовать конструкции типа a = !!b ^ !!c и аналогичные, а вместо них использовать записи, которые на 100% соответствуют НОРМАЛЬНОЙ ЛОГИКЕ, т.е. логике, доступной КАЖДОМУ ГРАМОТНОМУ человеку, а не только программисту-гуру. ибо даже программист-паскалист не сумеет смириться с подобным НЕЛОГИЧНЫМ поведением языка.

как видите, я предлагаю не использовать часть возможностей Си, которые реально приводят к взрыву мозга у человека, который еще помнит логику здравого смысла. пусть они будут, но их следует избегать, как оператора goto - обходятся ведь без него те же самые гуру, хотя это явно требует разрастания кода... при таком добровольном самоограничение каждая запись будет выглядеть ровно так, какой смысл в ней заложен: что прочли, то и делается.
demiurg_spb
Цитата(ARV @ Mar 21 2013, 20:33) *
1. (a == TRUE) полностью эквивалентно (a == !0). читается это как "а эквивалентно не нулю" - это логическое утверждение, при а=25 оно истинно. я нигде не ошибся? однако, в Си ответ будет прямо противоположный!

Вы сильно ошибаетесь, т.к. оператор == применяется не только для булевых, но и для многих других типов.
Поэтому благодаря integer promotion int a; .. if (a == TRUE) - это сравнение двух целых чисел, а вот результатом этой операции является булева величина.
Поэтому (25==1) ложно, а (!!25) истинно. Не надо фантазировать на пустом месте и высасывать теории из пальца.
Вы можете себя самоограничивать как угодно, вплоть до полного отшельничества. Но не надо парить мозги читателям форума. Извините за прямоту.
XVR
Цитата(ARV @ Mar 21 2013, 20:33) *
1. (a == TRUE) полностью эквивалентно (a == !0). читается это как "а эквивалентно не нулю" - это логическое утверждение, при а=25 оно истинно. я нигде не ошибся? однако, в Си ответ будет прямо противоположный!
Вы забываете, что это все же программа на С, а не абстрактные математические выкладки. Не надо натягивать математическую логику туда, где ей не место.

Цитата
4. я придерживаюсь той точки зрения, что не смотря на то, что это нарушение логики возведено в стандарт, есть простой способ привести все в соответствии с логикой
Есть более простой способ - не пишите на С, если не можете провести линию между языком программирования и формальными математическими обозначениями rolleyes.gif

Цитата
а вместо них использовать записи, которые на 100% соответствуют НОРМАЛЬНОЙ ЛОГИКЕ, т.е. логике, доступной КАЖДОМУ ГРАМОТНОМУ человеку, а не только программисту-гуру.
Пока с такими записями возникли проблемы только у вас. У остальных участников форума с ними проблем нет.

Цитата
ибо даже программист-паскалист не сумеет смириться с подобным НЕЛОГИЧНЫМ поведением языка.
Это диагноз ? laughing.gif

Цитата
как видите, я предлагаю не использовать часть возможностей Си, которые реально приводят к взрыву мозга у человека, который еще помнит логику здравого смысла.
Не используйте, или вас насильно заставляют?

Цитата
при таком добровольном самоограничение каждая запись будет выглядеть ровно так, какой смысл в ней заложен: что прочли, то и делается.
Вынужден вас огорчить - любая запись делает ровно то, что в ней написано. Вопрос в другом - сможет это понять читатель, или нет. У всех пока получается, может вам на свое самообразование стоит посмотреть rolleyes.gif

ARV
у меня получается все понимать не хуже вашего. просто вы не задумываетесь над тем, каким догмам следуете, а я задумываюсь. я как раз и стараюсь писать в соответствии не только с формальными требованиями стандарта, но и в соответствии со здравым смыслом. я думал, что в понимании заинтересованы все... но видимо, я ошибался: мало кому надо, чтобы его код был более понятным, если для этого надо поступиться своим собственным мнением...

все давно пришли к соглашению, что "магические числа" зло - Си разрешает это, но все стараются этого избегать.
все давно пришли к соглашению, что goto зло - Си это разрешает, но все стараются этого избегать
все давно пришли к соглашению, что переменная counter предпочтительнее безликой k, что глобальные переменные зло и чем их меньше, тем лучше и т.д. - целые книги пишутся на тему качественного кода...
во всех де-факто устоявшихся случаях следование этим правилам приводит к увеличению писанины - все мирятся с этим, понимая плюсы.

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

к сожалению, я ошибся, думая, что коллеги-программисты готовы критически воспринимать действиетльность... оказывается это не так. придется быть как все - писать круто, а не просто...

Цитата(demiurg_spb @ Mar 22 2013, 09:40) *
Вы сильно ошибаетесь, т.к. оператор == применяется не только для булевых, но и для многих других типов.
Поэтому благодаря integer promotion int a; .. if (a == TRUE) - это сравнение двух целых чисел, а вот результатом этой операции является булева величина.
Поэтому (25==1) ложно, а (!!25) истинно. Не надо фантазировать на пустом месте и высасывать теории из пальца.
Вы можете себя самоограничивать как угодно, вплоть до полного отшельничества. Но не надо парить мозги читателям форума. Извините за прямоту.

булевого типа в Си не предусмотрено, как вам хорошо известно, уважаемый Сергей. это из-за попытки совместить исключительно численную ориентацию Си с булевой алгеброй (т.е. ЛОГИКОЙ) и происходят всякие бесконечные integer promotions - как попытка найти компромисс между тем, что хочется и тем, что выходит.

и, кстати, поскольку форум - это место высказывания СВОИХ мыслей, я не занимаюсь толкованием стандарта, таких специалистов тут и без меня полно. хотелось бы обсуждать именно мнения персон, а не то, что не подлежит обсуждению, поскольку стандарт. а у вас один ответ - ваше мнение никому не интересно, посколько не соответствует догмату.


Цитата(XVR @ Mar 22 2013, 11:57) *
Вы забываете, что это все же программа на С, а не абстрактные математические выкладки. Не надо натягивать математическую логику туда, где ей не место.
логике место всегда и везде, человек, не способный логически мыслить, это недоумок, если мягко выразиться. а программа на любом языке в большинстве случаев служит для выражения на машинно-понятном уровне именно математических выкладок.
igorle
Цитата
все давно пришли к соглашению, что goto зло - Си это разрешает, но все стараются этого избегать

Вы код кернела линукса видели? Там goto почти в каждом файле. Обычно используется как error handling
Цитата
все давно пришли к соглашению, что переменная counter предпочтительнее безликой k,

Для переменной цикла нет ничего лучше стандартной i, j или k. Посмотрите в том-же кернеле. У меня нет под линукса под рукой, но если вы можете, посмотрите результат вывода строк
grep -rw for . | grep -w i | wc -l
grep -rw for . | grep -w counter | wc -l
и расскажите нам, каких циклов вы нашли больше - с переменной цикла i, или counter.

Вы демострируете нежелание понять, почему Си работает так как он работает. Вы не слышите, что вам говорят ТРИ человека, но при этом именно остальных обвиняете в упертости и косности.

Я думаю, что язык Си просто не подходит для тех задач, которые вы решаете по ходу своей работы. И это корень ваших проблем.

Цитата
к сожалению, я ошибся, думая, что коллеги-программисты готовы критически воспринимать действиетльность... оказывается это не так. придется быть как все - писать круто, а не просто...

Вы будете смеяться, но прекрасное "как он дышит так и пишет, не стараясь угодить" - к программистам тоже относится. Лучше пишите, как считаете правильным.
demiurg_spb
Цитата(ARV @ Mar 22 2013, 14:21) *
булевого типа в Си не предусмотрено, как вам хорошо известно, уважаемый Сергей.
Допустим что типа bool условно нет (гляньте на досуге <stdbool.h>), но при всём этом, результатом сравнения, как и любой иной логической операции, является именно булева величина,
принимающая значение 0 или 1 - просто и со вкусом.
А вы ну никак не хотите этого осознать!

PS: меня как бы не Сергей зовут...
ARV
Цитата(igorle @ Mar 22 2013, 14:51) *
Вы демострируете нежелание понять, почему Си работает так как он работает. Вы не слышите, что вам говорят ТРИ человека, но при этом именно остальных обвиняете в упертости и косности.

Я думаю, что язык Си просто не подходит для тех задач, которые вы решаете по ходу своей работы. И это корень ваших проблем.

чтобы не впадать в заблуждение, не додумывайте мои высказывания - попытайтесь их понять, а потом обдумать. я понимаю, почему Си работает вот именно так. но мне это представляется нелогичным - разве я непонятно объяснил? вы понимаете, почему Си так работает - и это для вас единственный аргумент для возражений мне. дескать, солнце всходит на востоке, потому что это в природе его (как говорил Аристотель). мне такого объяснения мало - я ведь не спорю с солнцем... но почему бы не попытаться объяснить его поведение иначе? т.е. в контексте Си - почему бы вместо допустимой хитрой и противоречивой записи не применить допустимую, простую и непротиворечивую (но на пару символов длиннее)? неужели из-за пары символов весь сыр-бор?!

у меня нет проблем, кроме той, что имею наглость думать иначе. think different - это про меня sm.gif

Буратино
Цитата(igorle @ Mar 20 2013, 16:59) *
Теперь сравните с
c = !!a ^ !!b;


Прошу прощения, а почему не писать
Код
c = !a ^ !b;

Зачем два знака ?
demiurg_spb
Цитата(Буратино @ Mar 22 2013, 15:22) *
Прошу прощения, а почему не писать
Код
c = !a ^ !b;

Зачем два знака ?
+5 Молодец! Действительно незачем!
ARV
Цитата(demiurg_spb @ Mar 22 2013, 15:09) *
Допустим что типа bool условно нет (гляньте на досуге <stdbool.h>), но при всём этом, результатом сравнения, как и любой иной логической операции, является именно булева величина,
принимающая значение 0 или 1 - просто и со вкусом.
А вы ну никак не хотите этого осознать!

PS: меня как бы не Сергей зовут...

я дико извиняюсь! blush.gif видимо, в пылу полемики перепутал вас с Сергеем, который Борщ... прошу прощения.
но тем не менее, поймите: я отлично знаю, что и как длается по стандарту Си. я это осознал, давно и бесповоротно. вы можете осознать, что выражения "не равно нулю" и "равно чему угодно, кроме нуля" - это ЭКВИВАЛЕНТЫ? если да, то следующий вопрос: почему при записи этих высказываний ДОСЛОВНО на Си мы имеем потерю их эквивалентности: (a != 0) и (a == !0) ?! вы говорите - так положено, я не спорю. вы говорите, что для достижения полной эквивалентности надо записать иначе - и вот тут я спрашиваю - ЗАЧЕМ? куда проще признать, что !0 означает именно НЕ НОЛЬ, т.е. ЦЕЛОЕ МНОЖЕСТВО ЗНАЧЕНИЙ, как это и принято в математике, логике и вобще жизни, и поступать соответственно. при этом стандарт остается стандартом, типа как ограничение скорости на дороге - все его знают, но никто не соблюдает, но без печальных последствий sm.gif



Цитата(federal @ Mar 22 2013, 15:22) *
с такими в команде работать никому не пожелаю
я и сам не стал бы

кстати о птичках:
Цитата(demiurg_spb @ Mar 21 2013, 09:41) *
А я пишу иначе:
Код
b = (a!=0);
это как раз то, о чем я и толкую sm.gif

Цитата(demiurg_spb @ Mar 22 2013, 15:38) *
+5 Молодец! Действительно незачем!
обратите внимание: ни один из убежденных сторонников "лаконичности" Си и знатоков стандарта не заметил этого на протяжении двух дней! ни сын-профессионал, который отца учит, ни сам отец, ни кто-то еще... нужен ли еще один аргумент в пользу того, что неожиданная (но корректная!!!) запись НЕ ОБЛЕГЧАЕТ понимание НИ ДЛЯ КОГО?!
federal
Цитата(ARV @ Mar 22 2013, 15:59) *
ни сын-профессионал, который отца учит, ни сам отец

а вот за это уверенная 5 и респект! biggrin.gif
ViKo
Цитата(ARV @ Mar 22 2013, 14:59) *
куда проще признать, что !0 означает именно НЕ НОЛЬ, т.е. ЦЕЛОЕ МНОЖЕСТВО ЗНАЧЕНИЙ, как это и принято в математике, логике и вобще жизни

Тогда нужно будет признать, что !33 - тоже всё, что угодно, кроме 33. И т.п. Вы видите здесь приближение к человеческой логике? (a == !33) ? Я не вижу. laughing.gif А равно "не 33"? - вы так спрашиваете?
Цитата
нужен ли еще один аргумент в пользу того, что неожиданная (но корректная!!!) запись НЕ ОБЛЕГЧАЕТ понимание НИ ДЛЯ КОГО?!

Теперь буду пользоваться c = !a ^ !b; Спасибо еще раз! sm.gif
P.S. Во имя отца и сына... и святого Электроника! Аминь!
XVR
Цитата(ARV @ Mar 22 2013, 15:59) *
почему при записи этих высказываний ДОСЛОВНО на Си мы имеем потерю их эквивалентности: (a != 0) и (a == !0) ?! вы говорите - так положено, я не спорю. вы говорите, что для достижения полной эквивалентности надо записать иначе - и вот тут я спрашиваю - ЗАЧЕМ? куда проще признать, что !0 означает именно НЕ НОЛЬ, т.е. ЦЕЛОЕ МНОЖЕСТВО ЗНАЧЕНИЙ, как это и принято в математике, логике и вобще жизни,
Язык С был придуман для упрощения жизни программисту, которому не хотелось писать на ассемблере. Поэтому он практически дословно повторяет особенности той аппаратной платформы, для которой был создан. А эта платформа умела оперировать с числами, а не с множествами. Поэтому '!0' обозначает результат применения операции 'логическое отрицание' к числу 0. Результат этой операции 1. Просто число 1, хотя бы потому, что ни машина ни язык С напрямую с множествами не работают!

Если хотите что бы '!0' обозначало именно множество (как 'принято в математике, логике и вобще жизни') - вам нужен другой язык. Язык С не оперирует с абстрактными математическими понятиями. Возьмите Matlab - он умеет. Или возьмите С++ и библиотеку для работы с множествами - тогда ваше любимое выражение (a == !0) будет обозначать именно то, как 'принято в математике, логике и вобще жизни'

Цитата
нужен ли еще один аргумент в пользу того, что неожиданная (но корректная!!!) запись НЕ ОБЛЕГЧАЕТ понимание НИ ДЛЯ КОГО?!
'НИ ДЛЯ КОГО' - это лично вы? Все остальные вроде как на непонимание не жаловались rolleyes.gif
Это вполне нормальная и кристально прозрачная запись (по крайней мере для того, кто достаточно хорошо знает язык)


Цитата(Буратино @ Mar 22 2013, 15:22) *
Прошу прощения, а почему не писать
Код
c = !a ^ !b;

Зачем два знака ?

Можно еще понятнее (специально для ARV) -
Код
c = (!a) != (!b);

ViKo
Цитата(XVR @ Mar 22 2013, 15:58) *
Можно еще понятнее

можно и без скобок, для лаконичности
c = !a != !b;
... и без пробелов sm.gif
c = !a!=!b;
XVR
Цитата(ViKo @ Mar 22 2013, 17:14) *
... и без пробелов sm.gif
c = !a!=!b;
Угу, начинаем строительство забора laughing.gif
Буратино
А 100 процентов
Код
!а != !b
и только потом
Код
с =
то что получится? Может быть и правда согласно с приоритетами вычислится все, но хз как будет присваиватся!
ARV
Цитата(XVR @ Mar 22 2013, 16:58) *
Язык С был придуман для упрощения жизни программисту, которому не хотелось писать на ассемблере. Поэтому он практически дословно повторяет особенности той аппаратной платформы, для которой был создан. А эта платформа умела оперировать с числами, а не с множествами. Поэтому '!0' обозначает результат применения операции 'логическое отрицание' к числу 0. Результат этой операции 1. Просто число 1, хотя бы потому, что ни машина ни язык С напрямую с множествами не работают!
теперь уже и историческую справку в доказательство привели. а ведь "не 33" на самом деле обозначает "все что угодно, кроме 33". даже если процессор работает только с нулями и единицами. и уж точно это не единственный вариант.

Цитата(XVR @ Mar 22 2013, 16:58) *
Если хотите что бы '!0' обозначало именно множество (как 'принято в математике, логике и вобще жизни') - вам нужен другой язык. Язык С не оперирует с абстрактными математическими понятиями. Возьмите Matlab - он умеет. Или возьмите С++ и библиотеку для работы с множествами - тогда ваше любимое выражение (a == !0) будет обозначать именно то, как 'принято в математике, логике и вобще жизни'
как обычно, решение кардинальное - не нравится, не ешь. но не смей говорить, что не нравится! очевидно, что нежелание применять логику дает о себе знать...


Цитата(XVR @ Mar 22 2013, 16:58) *
'НИ ДЛЯ КОГО' - это лично вы? Все остальные вроде как на непонимание не жаловались rolleyes.gif
Это вполне нормальная и кристально прозрачная запись (по крайней мере для того, кто достаточно хорошо знает язык)
и именно поэтому 2 дня никто не заметил, что это слегка мутная кристальность... было написано a = !!b ^ !!c; а стало a = !b ^ !c; - для вас это все равно?! вы ведь тоже не поняли СРАЗУ, что это НЕ САМЫЙ ИДЕАЛЬНЫЙ вариант sm.gif а тривиальный a = (!c && cool.gif || (!b && c) понятен всем. или на самом деле здесь просто не было тех, кто достаточно хорошо знает язык? надо бы определиться sm.gif

повторяю для знатоков и тех, кто к ним себя причисляет:
1. я ЗНАЮ, как работает Си. и ПОНИМАЮ, почему и как работает a = !b ^ !c; и даже разницу между a != 0 и a == !0 в соответствии со стандартами Си приемлю. и даже историю создания языка мало-мало представляю
2. я вижу, что все просто следуют догматам веры, не задумываясь, именно поэтому никто и не заметил лишнего знака, ибо напрягать-то мозг лишний раз все равно никому не хочется, даже профессиональному гуру. показали работающий более краткий вариант - готов его применить, считая лучшим, и не надо напрягаться.
3. я осознаю, что если не стремиться буть круче, чем яйцо на пасху, то и на Си можно писать код, который с точки зрения процессора будет идеальным, а с точки зрения ЛЮБОГО человека красивым и понятным.
4. сторонников моего принципа "разумного самоограничения ради логики" здесь нет, потому что в синагоге кришне не молятся.
раз Кернигана из меня не вышло, придется переквалифицироваться в управдомы sm.gif
P.S. беда не в том, что ваши попытки подколоть меня своими "специально для ARV" попадают мимо, беда в том, что мимо вас попадают мои попытки донести мысль... (не а) не эквивалентно (не б) как раз является правильной записью утверждения об отсутсвии пересечения множеств... но вы даже не пытаетесь это осмыслить...
XVR
Цитата(ARV @ Mar 22 2013, 19:22) *
4. сторонников моего принципа "разумного самоограничения ради логики" здесь нет
Есть, вопрос лишь в критериях 'разумности'. Лично с моей точки зрения !c ^ !b более 'разумно', чем (c && !b ) || (!c && b )

И вообще, если банальный ^ вызывает столько вопросов, то что будет когда придется разбираться с действительно сложными конструкциями.

Например такой -
Код
if ( i && !(i&(i-1)) ) ...


или такой
Код
i = (i&0x33333333) + ((i>>2)&0x33333333);
i = (i&0x0F0F0F0F) + ((i>>4)&0x0F0F0F0F);
i = (i&0x00FF00FF) + ((i>>8)&0x00FF00FF);
i = (i&0x0000FFF) + ((i>>16)&0x0000FFFF);

?

ARV
XVR, не пытайтесь подловить меня на ВАШИХ мыслях. проблем с ^ у меня нет и не было - вы хоть читать умеете? я об этом пишу в каждом посте. и книжки про "элегантные алгоритмы" битовых операций я тоже читал, но все равно не применяю это по вышесказанным причинам - не потому, что не понимаю, а потому, что не считаю верным такой подход. то, чем занимаетесь вы, давно взял на себя оптимизирующий компилятор.

никакая сложная конструкция не заслуживает того, чтобы быть сложной. кроме повода программисту показать свою крутость... не старайтесь: сколько волка не корми, у слона все равно больше...
adnega
А меня несколько месяцев назад больно "ударила" следующая конструкция:
Код
if((a + CONST) > a) a += CONST;

Хотел сделать универсальный счетчик с насыщением, но при знаковом a и беззнаковом CONST не работает((
Молчу уже про разрядность a (решение должно быть универсальным) и многопоточный доступ...
Хотя на первый взгляд все логично...
demiurg_spb
Ещё один интересный вариант вброшу (нижеследующие функции эквивалентны):
Код
const char* f(int i)
{
    return "Hallo" + i;
}

const char* f(int i)
{
    const char *p = "Hallo";
    return &p[i];
}

const char* f(int i)
{
    return &"Hallo"[i];
}
ARV
я бы предпочел второй вариант, затем третий, и в самую последнюю очередь - первый.
если XVR привел пример "загадочного", но реально (хоть пока и не могу представить, в каких случаях) полезного кода, то в этих примерах ничего интересного нет, они явно надуманы, только для демонстрации возможностей.
XVR
Цитата(ARV @ Mar 22 2013, 19:33) *
то, чем занимаетесь вы, давно взял на себя оптимизирующий компилятор.
увы, далеко не все оптимизирующий компилятор может реально соптимизировать. Например мои 2 примера (если их написать в лоб - через циклы) он не сможет опознать

Цитата
никакая сложная конструкция не заслуживает того, чтобы быть сложной
Это не так. Иногда бывают нужны и сложные конструкции - например при оптимизации по скорости. Даже банальный memcpy на современных производительных архитектурах реализован далеко не как простой цикл побайтового копирования rolleyes.gif
ARV
XVR, если вы внимательны, то должны заметить, что я ваш последний пример выделил в категорию "иногда имеющих смысл". но все остальное, о чем мы говорили, а именно логические выражения, индексное обращение к строкам или массивам и т.п. вещи (а я говорил именно об их бессмысленной загадочности - началось все с невинного a[5] vs 5[a] и определения переменных с одинаковыми идентификаторами во вложенных блоках) как раз оптимизатор и кушает, и НИКАКОЙ ВЫГОДЫ эти записи не дают - примеры demiurg_spb как раз из этой оперы.
и даже для ваших примеров может оказаться так, что по сравнению с тупыми циклами выигрыш будет, скажем, только на 32-битных платформах, а на 8-битных может и проигрыш оказаться - тут еще вопрос, что будет лучше sm.gif
XVR
Цитата(ARV @ Mar 23 2013, 17:31) *
XVR, если вы внимательны, то должны заметить, что я ваш последний пример выделил в категорию "иногда имеющих смысл". но все остальное, о чем мы говорили, а именно логические выражения, индексное обращение к строкам или массивам и т.п. вещи (а я говорил именно об их бессмысленной загадочности - началось все с невинного a[5] vs 5[a] и определения переменных с одинаковыми идентификаторами во вложенных блоках) как раз оптимизатор и кушает, и НИКАКОЙ ВЫГОДЫ эти записи не дают - примеры demiurg_spb как раз из этой оперы.
С этим согласен. Я просто хотел подчеркнуть, что порог 'бессмысленной загадочности' весьма субъективная штука. По моему мнению (и это всего лишь мое мнение) проффесиональный програмист должен досконально знать средство производства (а это язык С в данном случае), и у него все вышеприведенные примеры (а именно 'логические выражения, индексное обращение к строкам или массивам и определения переменных с одинаковыми идентификаторами во вложенных блоках') не только не должно вызывать недоумения, он их вообще не должен замечать как что то необычное. Это все вполне заурядные и тривиальные вещи. Если же у человека есть проблемы с пониманием (причем на лету) этих конструкций - он не может считаться квалифицированным проффесиональным программистом. Ну не может проффесионал спотыкаться на самых базовых понятиях языка rolleyes.gif

По поводу a[5] vs 5[a] - зтого специально никто не добивался. Это всего лишь побочное следствие определения семантики языка. Очевидно использовать это в реальных программах смысла никакого нет.
ARV
Цитата(XVR @ Mar 23 2013, 19:27) *
Ну не может проффесионал спотыкаться на самых базовых понятиях языка rolleyes.gif

По поводу a[5] vs 5[a] - зтого специально никто не добивался. Это всего лишь побочное следствие определения семантики языка. Очевидно использовать это в реальных программах смысла никакого нет.

видимо, вы не прочли последние 3-4 страницы темы, а ограничились только парой последних моих сообщений. иначе вы бы должны были понять, что я не утверждал, что какие-либо конструкции Си должны (могут) быть непонятны профессионалу. я призывал и призываю профессионалов не использовать без нужды конструкции, которые могут быть непонятны другим. более того, я призывал отказаться от конструкций, которые используют логические противоречия в стандарте языка, о чем я и рассказывал. написание "загадочного" кода не должно быть признаком профессионализма, элитарности.

если вы пишите какой-то криптоалгоритм, и вам необходимо добиться сверхоптимальности - куда вам деться от идеально вылизанных алгоритмов вроде вашего примера (кстати, не вами придуманного, а ставшего практически классикой)? но вместо понятного эквивалента ЛОГИЧЕСКОГО XOR использовать гибрид логическо-математического выражения - ЗАЧЕМ?! это не дает никакого выигрыша, кроме отдаления от НАЧИНАЮЩИХ и просто середнячков. кстати, вы раздел форума видите? ДЛЯ НАЧИНАЮЩИХ - а вы начинаете показывать то, что не только начинающим, но и все остальным (с моей т.з.) лучше не видеть.


напомню вам, как пропустившему начало: я попросил убедительно доказать, что запись 5[a] хоть в каком-то случае кому-то реально помогла достичь положительного эффекта бОльшего, чем экономия пары символов в строке программы. и с этого момента понеслось: раз в стандарте есть, то надо всем это знать... а зачем - никто путно не объясняет. надо и все. ДОГМА. в торе все написано, читай тору и будешь умным. я такой подход не приемлю.

за последние 20 лет наверняка ни один программист на планете ничего не потерял бы, если бы вместо a = !b ^ !c писал бы полный эквивалент, абсолютно верный и логически выдержанный. и так далее. не все знания одинаково полезны. если вам нужно быть профессионалом только для того, чтобы легко разбираться в тарабарщине другого профессионала - я пас. профессионал с моей точки зрения должен быть выше этого и думать не о том, насколько его код "загадочен", а о том, какое впечатление он произведет на остальных. если, конечно, он вообще намерен думать о тех, кто будет на его код смотреть.

попытка выдать за "лаконичный идеал" какую-то шифрограмму вызывает у меня смех. пиписька не выросла, что таким способом надо выделиться, что ли?! ни одного аргумента, кроме обвинений в моей тупоумности, никто не привел в пользу всей этой "лаконичности". какой-то жалкий лепет про поддержку и сопровождение кода... да это смешно! написанный без загадок код сможет поддерживать и сопровождать сопливый пацан - и вот именно этого гуру и боится! как же, он (гуру) напишет, а какой-то троечник сумеет потом все понять и (не дай бог!) модифицировать! только этот аргумент я и вижу в качестве на самом деле весомого.

тем более не понимаю, для чего НУЖНО использовать такой код (с чего все и началось):

Код
{

int i = 1;

// bla-bla-bla с переменной i

   {

   int i = 2;

   // bla-bla-bla с переменной i

      {

       int i = 3;

       // bla-bla-bla с переменной i

      }

   }

}
это МОЖНО по стандарту, но я бы за такое "программирование" кастрировал бы тупыми ножницами, чтобы остановить династию таких "профессионалов". можете спорить со мной до упаду - мое мнение неизменно.

такое вот мое мнение.

igorle
Цитата(ARV @ Mar 23 2013, 20:32) *
тем более не понимаю, для чего НУЖНО использовать такой код (с чего все и началось):

Код
{

int i = 1;
// bla-bla-bla с переменной i
   {
   int i = 2;
   // bla-bla-bla с переменной i
      {
       int i = 3;
       // bla-bla-bla с переменной i
      }
   }
}
это МОЖНО по стандарту, но я бы за такое "программирование" кастрировал бы тупыми ножницами, чтобы остановить династию таких "профессионалов". можете спорить со мной до упаду - мое мнение неизменно.

такое вот мое мнение.

Вот уж не ожидал, что Вы до сих пор помните, с чего весь кипеж начался.
Я искренне удивлен, что Вы до сих пор не поняли, (хотя это было повторено много раз), что это код не для использования, а для того чтобы продемонстрировать как работает Си. В данном случае - в какой области действуют переменные. Одинаковое имя выбрано НАМЕРЕННО. Затем Вам показали, что В УЧЕБНЫХ целях полезно ПОНЯТЬ, почему 5[a] эквивалентно a[5]. Так писать в реальном коде никто не призывал. А писать так "0123456789abcdef"[i] - да, можно и бывает полезно.

В ответ Вы завелись. Досталось и здесь присутствующим, и Кенигану с Ричи. Хотя осторумнее с Вашей сторны было бы понять, о чем говорят опоненты.
Давайте еще раз попробуем.
Цитата
тем более не понимаю, для чего НУЖНО использовать такой код

Такой код НУЖНО использовать при обучении, для демонстрации области дейстия автоматических переменных.
ARV
Цитата(igorle @ Mar 24 2013, 00:02) *
такой код НУЖНО использовать при обучении, для демонстрации области дейстия автоматических переменных.
повторяю, если вы так и не поняли.

мое мнение проще, чем бублик: ТАКОЙ код НЕ НУЖНО использовать при обучении. обучать НУЖНО методам программирования и особенностям языка, которые имеют РЕАЛЬНУЮ ПОЛЬЗУ, а "элегантные возможности" НУЖНО постепенно забывать.

уча ЭТОМУ вы плодите "профессионалов", озабоченных тем, чтобы простое казалось сложным, логичное - загадочным, понятное - непонятным. отсутствие НЕОБХОДИМОСТИ использования автоматических переменных с ОДИНАКОВЫМИ идентификаторами (к примеру) ДОЛЖНО породить их естественное умирание даже в качестве примера.

все остальное - см. выше, я аргументировал по-моему достаточно. повторю еще раз, может в этот раз вы поймете: НЕ ВСЕ ЙОГУРТЫ ОДИНАКОВО ПОЛЕЗНЫ!!! НЕ НАДО ПРОБОВАТЬ НА ВКУС ДЕРЬМО, ЧТОБЫ ПОНЯТЬ, ЧТО ЭТО ДЕРЬМО. НЕ НАДО ДЕМОНСТРИРОВАТЬ ОПАСНОСТЬ СОВАНИЯ ПАЛЬЦЕВ В РОЗЕТКУ СОВАНИЕМ ТУДА ПАЛЬЦЕВ. НЕ НАДО ПОКАЗЫВАТЬ ГЛУПЫЙ СТИЛЬ ПРОГРАММИРОВАНИЯ В КАЧЕСТВЕ ДЕМОНСТРАЦИИ ШИРОТЫ ВОЗМОЖНОСТЕЙ.

никто на планете Земля не желает, чтобы бацилла чумы существовала наравне с человеком, хотя это естественный биологический вид, теоретически имеющий право на существование. бациллу чумы уничтожили - и все стали только счастливее. если прекратить использование (путем замалчивания и неприменения) того, о чем ратуете ВЫ & Ко, НЕ ПОСТРАДАЕТ НИКТО И НИЧТО, кроме самолюбия небольшой группы гуру. сами возможности стандарта при этом сохранятся, как ядерные боеприпасы - на всякий случай, хотя никто не применяет и не планирует (надеюсь!) их применение.

чтобы поставить, надеюсь, последнюю жирную точку в споре, привожу свое доказательство СОМНИТЕЛЬНОЙ ПОЛЬЗЫ "лаконичности и т.п.".

Код
#include <avr/io.h>

typedef char boo;

volatile uint8_t a, b, c;

boo var1(boo x, boo y){
   return (!x && y) || (x && !y);
}

boo var2(boo x, boo y){
   return !x ^ !y;
}

int main(void){
   b = 25;
   c = 70;
   a = var1(b,c);
   a = var2(b,c);
   PORTB = 12;
   while(1);
}


в этой заготовке кода, ремарим функцию var1 и соответственно ее вызов в main, компилируем WinAVR 20100110, оптимизация -Os и получаем 198 байт памяти программ. затем аналогично вымарываем var2, оставляя var1, компилируем с теми же настройками и получаем 194 байта памяти программ. после этого для смеху переопределяем тип boo на long, повторяем эксперименты и умираем от смеху по поводу того, как ЛАКОНИЧНАЯ ЗАПИСЬ дает ПРОИГРЫШ в результирующем коде (234 против 252 байт).

успехов вам в лаконизме! wink.gif

я все сказал sm.gif
Буратино
Скажите, а нужны скобки в этом коде?

Код
return (!x && y) || (x && !y);
ARV
Цитата(Буратино @ Mar 24 2013, 10:33) *
Скажите, а нужны скобки в этом коде?

Код
return (!x && y) || (x && !y);
формально - не нужны. боюсь, меня заплюют, как обычно, но я ставлю скобки везде, где они позволяют визуально выделить "полезные" части выражения, чтобы, как обычно, никто не напрягал лишний раз голову, вспоминая о приоритетах операций.

в пользу моего подхода задайте вопрос любому своему знакомому: сколько будет два плюс два умножить на два? почти 99% с первой попытки отвечают 8, хотя правила арифметики знают даже двоечники...


ViKo
Цитата(igorle @ Mar 23 2013, 23:02) *
Затем Вам показали, что В УЧЕБНЫХ целях полезно ПОНЯТЬ, почему 5[a] эквивалентно a[5].
...
Такой код НУЖНО использовать при обучении, для демонстрации области дейстия автоматических переменных.

И... почему? Кто бы объяснил "на пальцах", как работает 5[a]. У классиков я такого не нашел. Про "зачем" не спрашиваю, считаю "незачем". sm.gif

Насчет скобок - стараюсь не писать лишние. Мне интереснее в список приоритетов заглянуть. И писать лаконично, "красиво".
Но вот последний Keil в своем редакторе выдает предупреждающие знаки, когда из-за приоритета операций, возможно, получится не то, чего я желаю. sm.gif
igorle
Цитата(ARV @ Mar 24 2013, 08:56) *
никто на планете Земля не желает, чтобы бацилла чумы существовала наравне с человеком, хотя это естественный биологический вид, теоретически имеющий право на существование. бациллу чумы уничтожили - и все стали только счастливее.

Вот смотрите до чего вы докатились. Вы уже говорите о знаниях как о бацилле. Приравняли ЗНАНИЯ к ЧУМЕ. Средневековье какое-то. Завтра вы начнете книгу K&R жечь на кострах.

Интересно, а как вы, не обремененный лишними знаниями, будете писать несложные, но выходящие за рамки банальных знаний функции.

Как вы и ваши ученики будут писать прототип функции с одним аргументом, получающей
1) указатель на массив типа int a[10][10];
2) указатель на массив типа int *a[10];
3) указатель на функцию, получающую в качестве аргумента указатель из первого вопроса, а возвращающую указатель из второго вопроса.

Надеюсь вы не считаете, что подобные функции никому не нужны?

Цитата(ViKo @ Mar 24 2013, 11:52) *
И... почему? Кто бы объяснил "на пальцах", как работает 5[a]. У классиков я такого не нашел. Про "зачем" не спрашиваю, считаю "незачем". :)

Совсем на пальцах
a[5] эквивалентно *(a+5)
От перемены мест слагаемых...
dxp
QUOTE (XVR @ Mar 23 2013, 22:27) *
По поводу a[5] vs 5[a] - зтого специально никто не добивался. Это всего лишь побочное следствие определения семантики языка. Очевидно использовать это в реальных программах смысла никакого нет.

Согласился бы с более мягкой формулировкой: "...использовать это в реальных программах настоятельной необходимости нет". Потому что, иногда такая запись, имхо, лучше акцентирует замысел. Например, есть несколько массивов, и надо пройтись по энному - скажем, пятому - элементу всех массивов:
CODE
#include <stdio.h>

int A1[10] = { 1,2,3,4,5,6,7,8,9,0 };
int A2[10] = { 11,22,33,44,55,66,77,88,99,10 };
int A3[10] = { 111,222,333,444,555,666,777,888,999,100 };

int *p[] = { A1, A2, A3 };

int main()
{
    for(int i = 0; i < sizeof(p)/sizeof(p[0]); ++i)
    {
        printf("%d\n", 5[p[i]]);
        printf("%d\n", p[i][5]);
    }
    return 0;
}

Вывод, очевидно, работает одинаково:
6
6
66
66
666
666

но запись 5[p[i]], имхо, заметно выразительнее в данном контексте, чем p[i][5] - мы именно подчёркиваем, что выбираем конкретный элемент всех массивах, а не просто перебираем массивы с какой-то дальнейшей целью - выбор какого-то элемента, как в данном примере. Когда я вижу такую запись, я полагаю, что программист именно хотел сделать акцент этой особенности алгоритма. Мелочь, но к месту. Совершенно согласен, что профессиональный квалифицированный программист должен безо всякого напряжения и ломки воспринимать такого рода конструкции. Признаюсь, что на заре освоения С, когда столкнулся в первый раз с такой записью, испытал лёгкий культурный шок. sm.gif Это мотивировало помедитировать над этой темой, через некоторое время всё встало на свои места.
ViKo
Цитата(igorle @ Mar 24 2013, 11:06) *
Совсем на пальцах
a[5] эквивалентно *(a+5)
От перемены мест слагаемых...

... получаем *(5+a). А дальше? "Еще нежнее..."
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.