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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
k000858
Открыл глаза
Сообщения: 44
Зарегистрирован: Сб июн 14, 2008 11:51:50

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

Сообщение k000858 »

Всем привет. изучаю теорию по Си. есть один вопросик, ответ на который никак не могу найти.
хорошо понимаю, как работает данное вырожение с оператором if
if (a>b && b>c) {}

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

Объясните плиз
Аватара пользователя
md5sum
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

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

Сообщение md5sum »

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

if(a & b) {}

Ести битовое И операндов a и b !=0, то true
— Не говорите мне что делать и я не скажу куда Вам идти...
k000858
Открыл глаза
Сообщения: 44
Зарегистрирован: Сб июн 14, 2008 11:51:50

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

Сообщение k000858 »

md5sum писал(а):

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

if(a & b) {}

Ести битовое И операндов a и b !=0, то true

хм. вроде понял.
то есть if(a) {} - это "если а!=0" так?
Rusja2008
Открыл глаза
Сообщения: 68
Зарегистрирован: Пн окт 06, 2008 15:51:58
Откуда: Черкассы

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

Сообщение Rusja2008 »

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

А конкретно в Вашем случае if(a & b) {} условие будет выполнятся только если логическое & между a и b будет истино.
Последний раз редактировалось Rusja2008 Пт апр 08, 2011 15:20:00, всего редактировалось 2 раза.
Не умееш - не берись, но не взявшись не научишся.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

k000858 писал(а):то есть if(a) {} - это "если а!=0" так?

Да, перефразирую в общем виде
if(выражение)
{
делаем если выражение = истина, т.е. ≠ 0;
};
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

Gudd-Head писал(а):
k000858 писал(а):то есть if(a) {} - это "если а!=0" так?

Да, перефразирую в общем виде
if(выражение)
{
делаем если выражение = истина, т.е. ≠ 0;
};

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

Мой уютный бложик... заходите!
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

ARV писал(а):правильнее было бы перефразировать без упоминания несуществующих в Си терминов "истина" и т.п. - просто "если выражение не равно нулю".

Т.е. результат сравнения a>b может быть либо нулём, либо...? :)
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

Gudd-Head писал(а):Т.е. результат сравнения a>b может быть либо нулём, либо...? :)

либо НЕ НУЛЕМ :) обычно 1, но это нигде не сказано, рассчитывать на это нельзя. НЕ НОЛЬ - и точка.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
md5sum
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

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

Сообщение md5sum »

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

Вот и ввели человека в заблуждение - логическое И: &&
А в данном примере 0x55 & 0xaa дадут в результате 0 и условие не выполнится.
Да и как правильно сказал ARV - нет значений ИСТИНА и ЛОЖЬ - есть ноль и не ноль
if (a & b) {} дословно переводится: если бивое "и" между а и b отлично от 0 то ...
— Не говорите мне что делать и я не скажу куда Вам идти...
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение 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.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение 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");
не правда ли? Конечно, для тех, кто знает язык :-). Собственно, с человеческими языками аналогично. Владея терминологией, можно сказать коротко. Но понятно только другим владеющим терминологией.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

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

Мой уютный бложик... заходите!
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

Это мое личное мнение, но я считаю, что Сишное представление логических значений в виде целочисленных по сравнению с Фортрановскими или Паскаль-Дельфийскими True и False менее строго и хотя может дать простор для трюков вроде приведенных avreal'ом, но леко может и запутать. А тут - как в уголовном кодексе - вычисляй и преобразовывай что хошь, но результат True или False - и вердикт присяжных обжалованию не подлежит.
Конечно, на вкус и цвет - свой велосипед, не нравится - не используй.
Аватара пользователя
Alexeus
Вымогатель припоя
Сообщения: 690
Зарегистрирован: Вс мар 04, 2007 01:17:12

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

Сообщение Alexeus »

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

char a;
char x=100;
char y=8;
a=x/y; //результат= 12.5, что будет в а? (cvavr не ругается)
Последний раз редактировалось Alexeus Пт апр 08, 2011 13:31:31, всего редактировалось 1 раз.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

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

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

Мой уютный бложик... заходите!
Аватара пользователя
Alexeus
Вымогатель припоя
Сообщения: 690
Зарегистрирован: Вс мар 04, 2007 01:17:12

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

Сообщение Alexeus »

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

я конечно понимаю, что это особое удовольствие для опытных людей пнуть кого то из незнаек типа меня, но все же 100/8 вообще то 12.5, а 12*8=96, (если верить калькулятору, а не особой философии с++) ну это так, к слову... так что вопрос остается открытым.
Последний раз редактировалось Alexeus Пт апр 08, 2011 13:39:41, всего редактировалось 1 раз.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

Мой уютный бложик... заходите!
Аватара пользователя
Alexeus
Вымогатель припоя
Сообщения: 690
Зарегистрирован: Вс мар 04, 2007 01:17:12

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

Сообщение Alexeus »

ну значит все-таки особенности си. хорошо, спасибо. )
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

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

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

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

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

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

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

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

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

Как у медиков -- можно сказать коротко «синдром Тако-Гото на фоне развития Отой-Бяки» и специалисту всё понятно. Студенту придётся разжёвывать на три страницы. Так что, заставлять и медицинских «гуру» общаться между собой (в том числе в доступных для прочтения студентами статьях в журналах) «как для студента»? Пусть студент подтягивается или упрощать всё -- чтобы следующий студент не понял уже и то упрощённое и упрощать дальше?
Я все эти штучки видел в чужом коде и получал массу удовольствия от разбора и понимания. Чего и всем желаю (в том числе и того, чтобы были исходники, в которых есть чему поучиться).
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

я тоже аналогично: с одной стороны согласен, а с другой...

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

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

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

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

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

Мой уютный бложик... заходите!
Ответить

Вернуться в «Разные вопросы по МК»