Опубликован: 05.07.2006 | Доступ: свободный | Студентов: 4680 / 885 | Оценка: 4.12 / 3.74 | Длительность: 18:59:00
Лекция 3:

Типы, операции и выражения

2.6. Операции отношения и логические операции

Операциями отношения являются

>= > =< <

все они имеют одинаковое старшинство. Непосредственно за ними по уровню старшинства следуют операции равенства и неравенства:

== !=

которые тоже имеют одинаковое старшинство. операции отношения младше арифметических операций, так что выражения типа i<lim-1 понимаются как i<(lim-1 ), как и предполагается.

Логические связки && и || более интересны. Выражения, связанные операциями && и ||, вычисляются слева направо, причем их рассмотрение прекращается сразу же как только становится ясно, будет ли результат истиной или ложью. Учет этих свойств очень существенен для написания правильно работающих программ. Рассмотрим, например, оператор цикла в считывающей строку функции getline, которую мы написали в "лекции №1" .

for(i=0;i<lim-1 && (c=getchar()) 
!= '\n' && c != EOF; ++i) 
      s[i]=c;

Ясно, что перед считыванием нового символа необходимо проверить, имеется ли еще место в массиве s, так что условие i<lim-1 должно проверяться первым. И если это условие не выполняется, мы не должны считывать следующий символ.

Так же неудачным было бы сравнение 'c' с EOF до обращения к функции getchar: прежде чем проверять символ, его нужно считать.

Старшинство операции && выше, чем у ||, и обе они младше операций отношения и равенства. Поэтому такие выражения, как

i<lim-1 && (c = getchar()) != '\n' && c != EOF

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

(c = getchar()) != '\n'

скобки необходимы.

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

if( ! inword )

Вместо

if( inword == 0 )

Tрудно сказать, какая форма лучше. конструкции типа ! inword Читаются довольно удобно ("если не в слове"). Но в более сложных случаях они могут оказаться трудными для понимания.

Упражнение 2-1

Напишите оператор цикла, эквивалентный приведенному выше оператору for, не используя операции &&.

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

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

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

atoi(s)         /* convert s to integer */
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);
}

Kак уже обсуждалось в "лекции №1" , выражение

s[i] - '0'

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