Глава 8. Раскрытие выражений_________________________________779

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

Проверки в цикле while, операторе for или условии if чаще всего используются привычным способом. При достаточно простых условиях такой подход наверняка принесет успех. Проверки, например, могут быть такими:

if( a > 5)

while( k-- > 0)

for( int j = 0; j < MAX; j++)

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

Одним из способов упрощения проверок является вычленение избыточно сложных условий и создание встраиваемой (inline) функции, которая бы заменяла код проверки функцией с подходящим именем. Имя функции может больше сказать о функциональном назначении выражения или о сущности проверяемого условия. Кроме того, в теле функции всегда можно найти достаточно места для размещения комментариев. Это позволяет разгрузить участок программы вокруг цикла, а встраивание функции (заданием спецификатора inline) компенсирует возможные потери в производительности. Кроме того, если цикл производит какую-либо деятельность, то оформление всего цикла в виде функции сделает программу читабельнее и повысит шансы вашего кода на повторное использование.

Следующий фрагмент преобразует символы строки ASCIIZ в верхний регистр. Макрос toupper обрабатывает только один символ, в то время как преобразовывать подчас приходится целые слова и выражения.

char *msg = "Jumanji";

// Преобразует ASCIIZ-строку в верхний регистр

for( char *p = msg; *р; *р = (char)toupper(*p), р++);

// Получилось "JUMANJI"

Программа с таким фрагментом будет неудобочитаема. Если попытаться словами описать то, что делает этот фрагмент, то получится что-то вроде "Указателю присваивается строка; до тех пор, пока указатель не достигнет нулевого символа '\Q', вызывать макрос toupper для каждого символа и увеличивать значение указателя".

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