Перейти к содержанию
    

А 100 процентов

!а != !b

и только потом

с =

то что получится? Может быть и правда согласно с приоритетами вычислится все, но хз как будет присваиватся!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Язык С был придуман для упрощения жизни программисту, которому не хотелось писать на ассемблере. Поэтому он практически дословно повторяет особенности той аппаратной платформы, для которой был создан. А эта платформа умела оперировать с числами, а не с множествами. Поэтому '!0' обозначает результат применения операции 'логическое отрицание' к числу 0. Результат этой операции 1. Просто число 1, хотя бы потому, что ни машина ни язык С напрямую с множествами не работают!
теперь уже и историческую справку в доказательство привели. а ведь "не 33" на самом деле обозначает "все что угодно, кроме 33". даже если процессор работает только с нулями и единицами. и уж точно это не единственный вариант.

 

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

 

 

'НИ ДЛЯ КОГО' - это лично вы? Все остальные вроде как на непонимание не жаловались :rolleyes:

Это вполне нормальная и кристально прозрачная запись (по крайней мере для того, кто достаточно хорошо знает язык)

и именно поэтому 2 дня никто не заметил, что это слегка мутная кристальность... было написано a = !!b ^ !!c; а стало a = !b ^ !c; - для вас это все равно?! вы ведь тоже не поняли СРАЗУ, что это НЕ САМЫЙ ИДЕАЛЬНЫЙ вариант :) а тривиальный a = (!c && B) || (!b && c) понятен всем. или на самом деле здесь просто не было тех, кто достаточно хорошо знает язык? надо бы определиться :)

 

повторяю для знатоков и тех, кто к ним себя причисляет:

1. я ЗНАЮ, как работает Си. и ПОНИМАЮ, почему и как работает a = !b ^ !c; и даже разницу между a != 0 и a == !0 в соответствии со стандартами Си приемлю. и даже историю создания языка мало-мало представляю

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

3. я осознаю, что если не стремиться буть круче, чем яйцо на пасху, то и на Си можно писать код, который с точки зрения процессора будет идеальным, а с точки зрения ЛЮБОГО человека красивым и понятным.

4. сторонников моего принципа "разумного самоограничения ради логики" здесь нет, потому что в синагоге кришне не молятся.

раз Кернигана из меня не вышло, придется переквалифицироваться в управдомы :)

P.S. беда не в том, что ваши попытки подколоть меня своими "специально для ARV" попадают мимо, беда в том, что мимо вас попадают мои попытки донести мысль... (не а) не эквивалентно (не б) как раз является правильной записью утверждения об отсутсвии пересечения множеств... но вы даже не пытаетесь это осмыслить...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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);

?

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А меня несколько месяцев назад больно "ударила" следующая конструкция:

if((a + CONST) > a) a += CONST;

Хотел сделать универсальный счетчик с насыщением, но при знаковом a и беззнаковом CONST не работает((

Молчу уже про разрядность a (решение должно быть универсальным) и многопоточный доступ...

Хотя на первый взгляд все логично...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ещё один интересный вариант вброшу (нижеследующие функции эквивалентны):

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];
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

если XVR привел пример "загадочного", но реально (хоть пока и не могу представить, в каких случаях) полезного кода, то в этих примерах ничего интересного нет, они явно надуманы, только для демонстрации возможностей.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

то, чем занимаетесь вы, давно взял на себя оптимизирующий компилятор.
увы, далеко не все оптимизирующий компилятор может реально соптимизировать. Например мои 2 примера (если их написать в лоб - через циклы) он не сможет опознать

 

никакая сложная конструкция не заслуживает того, чтобы быть сложной
Это не так. Иногда бывают нужны и сложные конструкции - например при оптимизации по скорости. Даже банальный memcpy на современных производительных архитектурах реализован далеко не как простой цикл побайтового копирования :rolleyes:

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

XVR, если вы внимательны, то должны заметить, что я ваш последний пример выделил в категорию "иногда имеющих смысл". но все остальное, о чем мы говорили, а именно логические выражения, индексное обращение к строкам или массивам и т.п. вещи (а я говорил именно об их бессмысленной загадочности - началось все с невинного a[5] vs 5[a] и определения переменных с одинаковыми идентификаторами во вложенных блоках) как раз оптимизатор и кушает, и НИКАКОЙ ВЫГОДЫ эти записи не дают - примеры demiurg_spb как раз из этой оперы.

и даже для ваших примеров может оказаться так, что по сравнению с тупыми циклами выигрыш будет, скажем, только на 32-битных платформах, а на 8-битных может и проигрыш оказаться - тут еще вопрос, что будет лучше :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну не может проффесионал спотыкаться на самых базовых понятиях языка :rolleyes:

 

По поводу 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

      }

   }

}

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

 

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

{

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" - да, можно и бывает полезно.

 

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

Давайте еще раз попробуем.

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

Такой код НУЖНО использовать при обучении, для демонстрации области дейстия автоматических переменных.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

такой код НУЖНО использовать при обучении, для демонстрации области дейстия автоматических переменных.
повторяю, если вы так и не поняли.

 

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

 

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

 

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

 

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

 

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

 

#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 байт).

 

успехов вам в лаконизме! ;)

 

я все сказал :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Скажите, а нужны скобки в этом коде?

 

 return (!x && y) || (x && !y);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...