"Андрей Богатырев. Хрестоматия по программированию на Си в Unix" - читать интересную книгу автора

else .......;

1.55. В чем ошибка (для знающих язык "Паскаль")?

int x = 12;
if( x < 20 and x > 10 ) printf( "O'K\n");
else if( x > 100 or x < 0 ) printf( "Bad x\n");
else printf( "x=%d\n", x);

Напишите

#define and &&
#define or ||

1.56. Почему программа зацикливается? Мы хотим подсчитать число пробелов и табуля-
ций в начале строки:

int i = 0;
char *s = " 3 spaces";
while(*s == ' ' || *s++ == '\t')
printf( "Пробел %d\n", ++i);

Ответ: логические операции || и && выполняются слева направо; как только какое-то
условие в || оказывается истинным (а в && ложным) - дальнейшие условия просто не
вычисляются. В нашем случае условие *s==' ' сразу же верно, и операция s++ из второго
условия не выполняется! Мы должны были написать хотя бы так:

while(*s == ' ' || *s == '\t'){
printf( "Пробел %d\n", ++i); s++;
}

С другой стороны, это свойство || и && черезвычайно полезно, например:

if( x != 0.0 && y/x < 1.0 ) ... ;

Если бы мы не вставили проверку на 0, мы могли бы получить деление на 0. В данном же
случае при x==0 деление просто не будет вычисляться. Вот еще пример:

int a[5], i;
for(i=0; i < 5 && a[i] != 0; ++i) ...;

Если i выйдет за границу массива, то сравнение a[i] с нулем уже не будет вычисляться,
т.е. попытки прочесть элемент не входящий в массив не произойдет.
Это свойство && позволяет писать довольно неочевидные конструкции, вроде

if((cond) && f());
что оказывается эквивалентным
if( cond ) f();

Вообще же