Может возникнуть вопрос, по какой причине, учитывая, что программа выполняется в цикле, пользователь лишен возможности ввести какие-то дополнительные данные после ввода символа q. Когда функция scanf() не может прочитать данные в указанной форме, она оставляет этот не соответствующий ее требованиям ввод на месте для его чтения в следующий раз. Следовательно, после неудавщейся попытки чтения символа q как целого числа функция scanf() оставляет q на месте. На следующей итерации цикла scanf() пытается выполнить считывание с того места, где оно было остановлено в последний раз — там, где остался символ q. Функция scanf() снова не может прочитать q как целое число, так что этот пример демонстрирует не только возникновение бесконечного цикла, но также и цикла безуспешных попыток чтения. Словом, результат получается довольно плачевный, и хорошо, что компьютеры пока еще лишены чувств. Слепое следование неразумным инструкциям для компьютера столь же бесперспективно, как и попытка предсказать ситуацию на фондовой бирже на ближайшее десятилетие.
Не используйте знак = вместо ==. В некоторых языках программирования (скажем, BASIC) для представления операции присваивания и операции проверки на равенство применяется один и тот же символ, однако это совершенно разные операции (рис. 6.2).

Рис. 6.2. Операция отношения == и операция пршдаивания =
Операция присваивания устанавливает значение переменной, указанной слева от знака операции. С другой стороны, операция проверки на равенство выясняет, эквивалентны ли левая и правая части операции. Она не изменяет значение переменной, расположенной слева, если она указана. Рассмотрим пример:
canoes =5 <- Присваивает значение 5 переменной canoes
canoes == 5 <- Проверяет, имеет ли переменная canoes значение 5
Будьте внимательны во время применения операции. Компилятор позволит вам использовать неподходящую форму, выдавая результат, который будет отличаться от ожидаемого. (Однако из-за того, что очень много программистов слишком часто
212 глава 6 неправильно применяли операцию =, большинство компиляторов выводит на экран предупреждение о том, что возможно предполагалась другая операция.) Если одно из сравниваемых значений является константой, его можно поместить слева от знака операции сравнения, чтобы облегчить выявление ошибки:
5 = canoes <- Синтаксическая ошибка
5 = canoes <- Проверяет, имеет ли переменная canoes значение 5
Смысл в том, что присваивать значение константе не допускается, поэтому компилятор трактует такую операцию присваивания как синтаксическую ошибку. Многие практикующие программисты в выражениях проверки на равенство первой указывают константу.
Итак, операции отношения используются для построения условных выражений. Выражения отношений имеют значение 1, если они истинны, и 0, если ложны. В операторах (таких как while и if), где обычно применяются выражения отношений в качестве условий проверки, могут использоваться любые выражения, при этом их ненулевые значения интерпретируются как “истина”, а нулевые — как “ложь”.
НОВЫЙ ТИП _Bool
Переменные, предназначенные для представления истинных и ложных значений, в языке С традиционно имеют тип int. В стандарте С99 для переменных такого вида был введен тип Bool. Тип получил свое название в честь Джорджа Буля (George Boole), английского математика, который разработал алгебраическую систему, позволяющую формулировать и решать логические задачи. В программировании переменные, представляющие истинные и ложные значения, известны как булевские, так что именем типа для этих переменных в языке С является Bool. Переменная типа Bool может иметь только значения 1 (“истина”) и 0 (“ложь”). Если вы попытаетесь присвоить переменной Bool ненулевое числовое значение, то она получит значение 1, отражая тот факт, что любое ненулевое значение в С трактуется как “истина”.
В листинге 6.9 исправлено условие проверки, указанное в листинге 6.8, и переменная status типа int заменена переменной input_is_good типа Bool. Назначение булевским переменным имен, но которым ясно, что они принимают истинные и ложные значения, является общей практикой.
Листинг 6.9. Программа boolean.с

Управляющие операторы С: циклы 213
Обратите внимание на то, как в коде присваивает результат сравнения переменной:
Читать дальше