Язык программирования Си (Ритчи, Керниган) - страница 39

, однако их приоритеты ниже, чем приоритет операторов отношения и равенства. Из сказанного следует, что выражение вида

>i ‹ lim-1 && (с = getchar()) != '\n' && с != EOF

не нуждается в дополнительных скобках. Но, так как приоритет != выше, чем приоритет присваивания, в

>(с = getchar()) != '\n'

скобки необходимы, чтобы сначала выполнить присваивание, а затем сравнение с '\n'.

По определению численным результатом вычисления выражения отношения или логического выражения является 1, если оно истинно, и 0, если оно ложно.

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

>if (!valid)

что эквивалентно

>if (valid == 0)

Трудно сказать, какая из форм записи лучше. Конструкция вида !valid хорошо читается ("если не правильно"), но в более сложных выражениях может оказаться, что ее не так-то легко понять.

Упражнение 2.2. Напишите цикл, эквивалентный приведенному выше or-циклу, не пользуясь операторами && и ||.

2.7 Преобразования типов

Если операнды оператора принадлежат к разным типам, то они приводятся к некоторому общему типу. Приведение выполняется в соответствии с небольшим числом правил. Обычно автоматически производятся лишь те преобразования, которые без какой-либо потери информации превращают операнды с меньшим диапазоном значений в операнды с большим диапазоном, как, например, преобразование целого в число с плавающей точкой в выражении вроде f+i. Выражения, не имеющие смысла, например число с плавающей точкой в роли индекса, не допускаются. Выражения, в которых могла бы теряться информация (скажем, при присваивании длинных целых переменным более коротких типов или при присваивании значений с плавающей точкой целым переменным), могут повлечь за собой предупреждение, но они допустимы.

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

>/* atoi: преобразование s в целое */

>int atoi(char s[])

>{

> int i, n;

> n = 0;

> for (i = 0; s[i] ›= '0' && s[i] ‹= '9'; ++i)

>  n = 10 * n + (s[i] - '0');

> return n;

>}

Как мы уже говорили в главе 1, выражение

>s[i] -'0'

дает числовое значение символа, хранящегося в s[i], так как значения '0', '1' и пр. образуют непрерывную возрастающую последовательность.

Другой пример приведения char к int связан с функцией lower, которая одиночный символ из набора ASCII, если он является заглавной буквой, превращает в строчную. Если же символ не является заглавной буквой, lower его не изменяет.