Выражения
Некоторые конструкции кажутся специально созданными для того, чтобы сбить читателя с толку. Например, применение оператора ?: может привести к появлению абсолютно загадочного кода:
? 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.
Побочные эффекты есть не только у инкремента и декремента; ввод-вывод – еще один потенциальный источник возникновения закулисных действий.