"Андрей Богатырев. Хрестоматия по программированию на Си в Unix" - читать интересную книгу автораоднако, что пробелы после # перед именем директивы вполне допустимы. В четвертом
случае показана характерная опечатка - символ ; после определения. В результате напи- санный printf() заменится на printf( "n=%d\n", 12; ); где лишняя ; даст синтаксическую ошибку. В пятом случае ошибки нет, но нас ожидает неприятность в строке p=4-X; которая расширится в строку p=4--2; являющуюся синтаксически неверной. Чтобы избежать подоб- ной ситуации, следовало бы написать p = 4 - X; /* через пробелы */ но еще проще (и лучше) взять макроопределение в скобки: #define X (-2) 1.45. Напишите функцию max(x, y), возвращающую большее из двух значений. Напишите аналогичное макроопределение. Напишите макроопределения min(x, y) и abs(x) (abs - модуль числа). Ответ: #define abs(x) ((x) < 0 ? -(x) : (x)) #define min(x,y) (((x) < (y)) ? (x) : (y)) Зачем x взят в круглые скобки (x)? Предположим, что мы написали #define abs(x) (x < 0 ? -x : x ) вызываем abs(-z) abs(a|b) получаем (-z < 0 ? --z : -z ) (a|b < 0 ? -a|b : a|b ) У нас появилась "дикая" операция --z; а выражение a|b<0 соответствует a|(b<0), с сов- сем другим порядком операций! Поэтому заключение всех аргументов макроса в его теле в круглые скобки позволяет избежать многих неожиданных проблем. Придерживайтесь этого правила! Вот пример, показывающий зачем полезно брать в скобки все определение: #define div(x, y) (x)/(y) При вызове А. Богатырев, 1992-95 - 19 - Си в UNIX z = sizeof div(1, 2); превратится в z = sizeof(1) / (2); что равно sizeof(int)/2, а не sizeof(int). Вариант |
|
|