Страница 19 из 386

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт апр 07, 2011 09:24:56
k000858
Всем привет. изучаю теорию по Си. есть один вопросик, ответ на который никак не могу найти.
хорошо понимаю, как работает данное вырожение с оператором if
if (a>b && b>c) {}

но часто встречаю другое вырожение в программах и вот никак не могу понять, как работает
if(a & b) {}

Объясните плиз

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт апр 07, 2011 09:28:53
md5sum

Код: Выделить всё

if(a & b) {}
Ести битовое И операндов a и b !=0, то true

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт апр 07, 2011 09:31:08
k000858
md5sum писал(а):

Код: Выделить всё

if(a & b) {}
Ести битовое И операндов a и b !=0, то true
хм. вроде понял.
то есть if(a) {} - это "если а!=0" так?

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт апр 07, 2011 10:41:44
Rusja2008
Да уж, с этими a & b != 0 запутатся проще простого.
Ориентируйтесь на то, что код в скобках после if(a) {} , будет выполнятся в случае если а истинно. А что стоит вместо а, толи a & b или a && b или a>b, или что то другое, порядка выполнения действия в скобках не меняет.

А конкретно в Вашем случае if(a & b) {} условие будет выполнятся только если логическое & между a и b будет истино.

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт апр 07, 2011 10:45:44
Gudd-Head
k000858 писал(а):то есть if(a) {} - это "если а!=0" так?
Да, перефразирую в общем виде
if(выражение)
{
делаем если выражение = истина, т.е. ≠ 0;
};

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт апр 07, 2011 10:57:05
ARV
Gudd-Head писал(а):
k000858 писал(а):то есть if(a) {} - это "если а!=0" так?
Да, перефразирую в общем виде
if(выражение)
{
делаем если выражение = истина, т.е. ≠ 0;
};
правильнее было бы перефразировать без упоминания несуществующих в Си терминов "истина" и т.п. - просто "если выражение не равно нулю".

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт апр 07, 2011 12:44:19
Gudd-Head
ARV писал(а):правильнее было бы перефразировать без упоминания несуществующих в Си терминов "истина" и т.п. - просто "если выражение не равно нулю".
Т.е. результат сравнения a>b может быть либо нулём, либо...? :)

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт апр 07, 2011 13:04:41
ARV
Gudd-Head писал(а):Т.е. результат сравнения a>b может быть либо нулём, либо...? :)
либо НЕ НУЛЕМ :) обычно 1, но это нигде не сказано, рассчитывать на это нельзя. НЕ НОЛЬ - и точка.

Re: Вопросы по С/С++ (СИ)

Добавлено: Чт апр 07, 2011 20:13:43
md5sum
Rusja2008 писал(а):А конкретно в Вашем случае if(a & b) {} условие будет выполнятся только если логическое & между a и b будет истино (по большому счету и a и b должны быть больше 0).
Вот и ввели человека в заблуждение - логическое И: &&
А в данном примере 0x55 & 0xaa дадут в результате 0 и условие не выполнится.
Да и как правильно сказал ARV - нет значений ИСТИНА и ЛОЖЬ - есть ноль и не ноль
if (a & b) {} дословно переводится: если бивое "и" между а и b отлично от 0 то ...

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт апр 08, 2011 00:54:27
avreal
Прошу прощения за занудство, но
Да, if(), while(), среднее выражение for(;;), логические операторы &&, || на входе работают в термианх "0" - "не 0".
Но при этом сами операторы сравнения и логические возвращают 0 или 1.
Т.е.

Код: Выделить всё

    int  a = 4;
    int b = 5;
    int с = 6;
    c +=  b > a;
    printf("%d %d %d\n", a > b, a < b, c);
напечатает 0 1 7
Стандарт C89, в остальных аналогично.
3.3.8 Relational operators
...
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if
the specified relation is true and 0 if it is false. The result has type int.
И сносочка
38. The expression a<b<c is not interpreted as in ordinary mathematics. As the syntax indicates, it means (a<b)<c ; in other
words, ``if a is less than b compare 1 to c ; otherwise compare 0 to c.''
А также
3.3.13 Logical AND operator
...
The && operator shall yield 1 if both of its operands compare unequal to 0, otherwise it yields 0.
The result has type int.
...
3.3.14 Logical OR operator
The || operator shall yield 1 if either of its operands compare unequal to 0, otherwise it yields 0. The result has type int.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт апр 08, 2011 01:10:08
avreal
Кстати, о птичках.
Интересные С-шные идиомы:

Код: Выделить всё

  int a, b;
  a = !!b;
Выше я забыл упомянуть ! в ряду логических операторов.
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 operandcompares equal to 0. The result has type int . The expression !E is equivalent to (0==E) .
Итого двойной ! приводит значение к 0 или 1, заменяя собой

Код: Выделить всё

 a =  b ? 1 : 0;
Ну и такое себе "логическое исключающее или":

Код: Выделить всё

  int a, b;
  if (!a != !b)  puts("Только одна из переменных a и b равна 0");
  if (!a == !b) puts("Обе переменные 0 либо обе не 0");
Неплохая замена

Код: Выделить всё

  int a, b;
  if ( (a == 0 && b != 0) || (a != 0 && b == 0) ) puts("Только одна из переменных a и b равна 0");
  if ( (a == 0 && b == 0) || (a != 0 && b != 0) ) puts("Обе переменные 0 либо обе не 0");
не правда ли? Конечно, для тех, кто знает язык :-). Собственно, с человеческими языками аналогично. Владея терминологией, можно сказать коротко. Но понятно только другим владеющим терминологией.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт апр 08, 2011 07:32:30
ARV
мне кажется, что разница в генерируемом коде вряд ли будет заметна... и если это так, мы снова можем получить ситуацию, когда программа написана лишь для демонстрации собственной крутости... не смотря на то, что Си позволяет писать "очень хитро накрученный" код, практически постоянно рекомендуют воздерживаться от этого.

ведь запись !a != !b гораздо непонятнее, чем более длинная "развернутая" запись. дело именно НЕ В КРАТКОСТИ, а в "элитарности". напомню бородатый анекдот про анекдоты в офицерском собрании, где их просто называли по номеру... понятно только избранным... и отсюда вывод: если твой код должен (может) быть доступен другим - пиши так, чтобы его понял любой. если считаешь, что "всяким разным" его понимать незачем - пиши как угодно, но не показывай никому "лишнему". маловероятно, что даже гуру так легко воспримет подобную запись...

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт апр 08, 2011 11:43:33
Jack_A
Это мое личное мнение, но я считаю, что Сишное представление логических значений в виде целочисленных по сравнению с Фортрановскими или Паскаль-Дельфийскими True и False менее строго и хотя может дать простор для трюков вроде приведенных avreal'ом, но леко может и запутать. А тут - как в уголовном кодексе - вычисляй и преобразовывай что хошь, но результат True или False - и вердикт присяжных обжалованию не подлежит.
Конечно, на вкус и цвет - свой велосипед, не нравится - не используй.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт апр 08, 2011 13:11:49
Alexeus
пишу в cvavr.
Подскажите пожалуйста, если переменная была заявлена как целая, а результат арифметической операции, который должен быть в нее занесен- с точкой, то автоматически округлится до целого или нужно округлять как то?

char a;
char x=100;
char y=8;
a=x/y; //результат= 12.5, что будет в а? (cvavr не ругается)

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт апр 08, 2011 13:22:38
ARV
Alexeus писал(а):cvavr.
Подскажите пожалуйста, если переменная была заявлена как целая, а результат арифметической операции, который должен быть в нее занесен- с точкой, то автоматически округлится до целого или нужно округлять как то?

char a;
char x=100;
char y=8;
a=x/y; //результат= 12.5, что будет в а? (cvavr не ругается)
во-первых, ругаться тут ни один компилятор не будет
во-вторых, ругаться тут можно только на вас, что вы не изучили язык Си - даже начатки его!
потому что результат деления х на y будет 12 - без всяких дробей и т.п. то есть ваш вопрос отсутствует в принципе.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт апр 08, 2011 13:34:58
Alexeus
честно говоря пользуюсь им по мере надобности необходимых мне знаний, и в процессе соответственно познаю. пока я этого вопроса не касался, а теперь нужно.

я конечно понимаю, что это особое удовольствие для опытных людей пнуть кого то из незнаек типа меня, но все же 100/8 вообще то 12.5, а 12*8=96, (если верить калькулятору, а не особой философии с++) ну это так, к слову... так что вопрос остается открытым.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт апр 08, 2011 13:37:44
ARV
Alexeus писал(а):100/8 вообще то 12.5, а 12*8=96, ну это так, к слову... так что вопрос остается открытым.
повторяю: в вашей программе результат от деления x на y будет 12, и никак иначе. это не к слову - это факт.

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт апр 08, 2011 13:41:27
Alexeus
ну значит все-таки особенности си. хорошо, спасибо. )

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт апр 08, 2011 14:15:26
avreal
ARV писал(а):ведь запись !a != !b гораздо непонятнее, чем более длинная "развернутая" запись. дело именно НЕ В КРАТКОСТИ, а в "элитарности"
С одной стороны, согласен.
С другой -- это вопрос не качественный (нормально/«элитарно»), а количественный -- вопрос порога «элитарности», зависящий от знаний и опыта.

Кому-то и запись

Код: Выделить всё

*dst++ = *src++;
непонятна, он скажет, что так пишут «чиста чтобы попонтоваться» и нет никакого смысла писать так «не кратко, а элитарно-непонятно», если можно написать просто и ясно

Код: Выделить всё

    *dst = *src;
    dst = dst + 1;
    src = src + 1;
(именно так, даже не ++dst; ++src;, так как «ну их в баню эти элитарные пре-/пост- операции, вечно думать, что за чем происходит и какое значенеи используется»).
А другому во второй записи на три строки «за деревьями не видно леса», она даже менее понятна («ой, а почему так расписано, тут что, не простое копирование?») и он предпочтет первую. Кстати, тут тоже современные компиляторы сделают вероятнее всего одинаковый код.

А ещё кому-то вообще практически непонятны С-шные указатели. Ну и? Не использовать вообще?
А битовые операции и сдвиги -- тут же на форуме часто непонимание наблюдается, всё подай запись PORTB.0 ...
Да весь С -- набор идиом разного уровня сложности. Начиная от классического while( (*dst++ = *src++) );

Это всё: и ++/--, и *=, и операции с указателями, и указатели на функции, и тернарная операция (особенно в сочетании с указателями), и иногда очень удобный оператор «запятая» -- своего рода «паттерны кодирования на С».
И всяко проще для понимания, чем С++ - ные навороты типа буста :-)

Как у медиков -- можно сказать коротко «синдром Тако-Гото на фоне развития Отой-Бяки» и специалисту всё понятно. Студенту придётся разжёвывать на три страницы. Так что, заставлять и медицинских «гуру» общаться между собой (в том числе в доступных для прочтения студентами статьях в журналах) «как для студента»? Пусть студент подтягивается или упрощать всё -- чтобы следующий студент не понял уже и то упрощённое и упрощать дальше?
Я все эти штучки видел в чужом коде и получал массу удовольствия от разбора и понимания. Чего и всем желаю (в том числе и того, чтобы были исходники, в которых есть чему поучиться).

Re: Вопросы по С/С++ (СИ)

Добавлено: Пт апр 08, 2011 14:40:43
ARV
я тоже аналогично: с одной стороны согласен, а с другой...

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

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

avreal, вы ведь признаете, что конструкция !a != !b вам далась не с наскоку? пришлось пораскинуть мозгами, не так ли? и наверняка очень многим достаточно компетентным программистам аналогично :))) а по-настоящему-то никакого выигрыша она не дает, ктоме удовольствия знать, что ты это постиг, а многие - нет.

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

P.S. на классический while(*dst++ = *src++); компилятор реагирует варнингом, что как-то настораживает - ой, не спроста это... :)