Иллюстрированный самоучитель по практике программирования

Выражения

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

? child=(!LC&&!RC)?0:(!LC?RC:LC);

Согласитесь, что, только разобрав все возможные варианты сравнений, можно догадаться, что же делает этот фрагмент. Приведенная ниже конструкция длиннее, но значительно проще, потому что возможные варианты видны сразу:

f (LC == 0 && RC == 0)
child = 0; else if (LC == 0)
child = RC; else
child = LC;

Операция ?: хороша только для коротких и простых выражений, где она может заменить четыре строки if-else одной, как в следующем примере:

max = (а > b)? а: b;

Или даже в таком случае:

printf("The list has %d item%s\n", n, n==1? "": "s");

Однако подобная замена все же не является распространенной.

Ясность и краткость – не одно и то же. Часто более ясный код будет и более коротким (как в примере со сдвигом битов), однако он может быть и, наоборот, более длинным (как в примере с if-else). Главным критерием выбора должна служить простота восприятия.

Будьте осторожны с побочными эффектами.
Операции типа ++ имеют побочные эффекты: они не только возвращают значение, но еще и изменяют операнд. Эти побочные эффекты иногда могут быть весьма удобны, но они же могут вызвать трудности из-за того, что получение значения и обновление переменной могут происходить не тогда, когда ожидается. В С и C++ порядок выполнения этих побочных эффектов вообще не определен, поэтому нижеприведенное множественное присваивание, скорее всего, будет выдавать неправильный ответ:

? str[i++] = str[i++] = ' ';

Смысл выражения – записать пробел в следующие две позиции строки str. Однако в зависимости от того, когда будет обновляться i, позиция в str может быть пропущена, и в результате переменная 1 будет увеличена только на 1. Разбейте выражение на два:

str[i++] = ' ';
str[i++] =''.-"';

Даже если в выражении содержится только один инкремент, результат может быть неоднозначным:

? array[i++] = i;

Если изначально i имеет значение 3, то элемент массива может принять значение 3 либо 4.

Побочные эффекты есть не только у инкремента и декремента; ввод-вывод – еще один потенциальный источник возникновения закулисных действий.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.