Пособие по практике программирования

       

только разобрав все возможные варианты


? 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, позиция в st r может быть пропущена, и в результате переменная 1 будет увеличена только на 1. Разбейте выражение на два:
str[i++] = ' ';
str[i++] =''.-"';
Даже если в вы ражении содержится только один инкремент, результат может быть неоднозначным:
? array[i++] = i;
Если изначально i имеет значение 3, то элемент массива может принять значение 3 либо 4.
Побочные эффекты есть не только у инкремента и декремента; ввод-вывод — еще один потенциальный источник возникновения закулисных действий.В следующем примере осуществляется попытка прочитать два взаимосвязанных числа из стандартного ввода:
scanf ("' &yr, &profit[yr]);
Выражение неверно, поскольку одна его часть изменяет уг, а другая использует ее. Значение prof it[yr] будет правильным только в том случае, если новое значение уг будет таким же, как и старое. Вы, наверное, думаете, что все дело в порядке вычисления аргументов, однако в действительности проблема здесь в том, что все аргументы scanf вычисляются до того, как эта операция вызывается на выполнение, так что &profit[yr] всегда будет вычисляться с использованием старого значения у г. Проблемы подобного рода могут возникнуть в любом языке программирования. Для исправления достаточно опять же разбить выражение на две части:
scanf("%d", &yr);
scanf("%d", &profit[yr]);
Будьте осторожны с любым выражением, вызывающим побочные эффекты.

Содержание раздела