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

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

2.10. Операции и выражения присваивания

Такие выражения, как

i = i + 2

в которых левая часть повторяется в правой части могут быть записаны в сжатой форме

i += 2

используя операцию присваивания вида +=.

Большинству бинарных операций (операций подобных +, которые имеют левый и правый операнд) соответствует операция присваивания вида оп=, где оп - одна из операций

+ - * / % << >> & ^ |!

Если е1 и е2 - выражения, то е1 оп= е2 эквивалентно

е1 = (е1) оп (е2)

за исключением того, что выражение е1 вычисляется только один раз. Обратите внимание на круглые скобки вокруг е2:

x *= y + 1

то

x = x * (y + 1)

не

x = x * y + 1

В качестве примера приведем функцию bitcount, которая подсчитывает число равных 1 битов у целого аргумента.

bitcount(n)   /* count 1 bits in n */
unsigned n;
(
int b;
for (b = 0; n != 0; n >>= 1)
   if (n & 01)
           b++;
return(b);
)

Не говоря уже о краткости, такие операторы присваивания имеют то преимущество, что они лучше соответствуют образу человеческого мышления. Мы говорим: "прибавить 2 к i " или "увеличить i на 2", но не "взять i, прибавить 2 и поместить результат опять в i ". Итак, i += 2. Кроме того, в громоздких выражениях, подобных

yyval[yypv[p3+p4] + yypv[p1+p2]] += 2

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

Мы уже использовали тот факт, что операция присваивания имеет некоторое значение и может входить в выражения; самый типичный пример

while ((c = getchar()) != EOF)

присваивания, использующие другие операции присваивания ( +=, -= и т.д.) также могут входить в выражения, хотя это случается реже.

типом выражения присваивания является тип его левого операнда.

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

В двоичной системе счисления операция x&(x-1) обнуляет самый правый равный 1 бит переменной x.(почему?) используйте это замечание для написания более быстрой версии функции bitcount.

2.11. Условные выражения

операторы

if (a > b)
    z = a;
 else
    z = b;

конечно вычисляют в z максимум из а и в. Условное выражение, записанное с помощью тернарной операции "?:", предоставляет другую возможность для записи этой и аналогичных конструкций. В выражении

е1 ? Е2 : е3

сначала вычисляется выражение е1. Если оно отлично от нуля (истинно), то вычисляется выражение е2, которое и становится значением условного выражения. В противном случае вычисляется е3, и оно становится значением условного выражения. Каждый раз вычисляется только одно из выражения е2 и е3. Таким образом, чтобы положить z равным максимуму из а и в, можно написать

z = (a > b) ? a : b; /* z = max(a,b) */

Следует подчеркнуть, что условное выражение действительно является выражением и может использоваться точно так же, как любое другое выражение. Если е2 и е3 имеют разные типы, то тип результата определяется по правилам преобразования, рассмотренным ранее в этой лекции. Например, если f имеет тип float, а n - тип int, то выражение

(n > 0) ? f : n

Имеет тип double независимо от того, положительно ли n или нет.

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

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

for (i = 0; i < n; i++) 
      printf("%6d%c",a[i],(i%10==9 || i==n-1) ? '\n' : ' ')

Символ перевода строки записывается после каждого десятого элемента и после n -го элемента. За всеми остальными элементами следует один пробел. Хотя, возможно, это выглядит мудреным, было бы поучительным попытаться записать это, не используя условного выражения.

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

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