Вход/Регистрация
Язык Си - руководство для начинающих
вернуться

Д. МАРТИН

Шрифт:

Можно ли ваше определение переделать так, чтобы SQUARE(x + 2) было равно 36? Конечно. Нам просто нужно больше скобок:

#define SQUARE(x) (x)*(x)

Тогда SQUARE(x + 2) становится (х + 2)*(х + 2), и мы получаем наше желанное умножение, так как перенесли скобки в строку замещения.

Однако это не решает всех наших проблем. Рассмотрим случаи, которые приводят к следующей строке на выходе: 100/SQUARE(2) превращается в 100/2*2 .

Вычисления следует вести слева направо, т. е. (100/2)*2 или 50*2 или 100.

Эту путаницу можно исправить, определив SQUARE(x) следующим образом:

#define SQUARE(x) (x*x)

Это даст 100/(2 *2), что в конечном счете эквивалентно 100/4 или 25.

Чтобы выполнить два последних примера, нам необходимо определение

#define SQUARE(x) ((x)*(x))

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

Даже эти предосторожности не спасают последний пример от беды: SQUARE(++ х) превращается в ++х * ++х и x увеличивается дважды - один раз до умножения и один раз после: ++х * ++х = 5*6 = 30.

(Так как порядок выполнения операций не установлен, то некоторые компиляторы превратят это в 6*5, но конечный результат будет тем же самым.)

Единственное лекарство в этом случае - не использовать ++х в качестве аргумента для макроопределения. Заметим, что ++х обычно работает как аргумент функции, так как ему присваивается значение 5, и затем это значение 5 передается функции.

МАКРООПРЕДЕЛЕНИЕ ИЛИ ФУНКЦИЯ?

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

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

Выбор макроопределения приводит к увеличению объема памяти, а выбор функции - к увеличению времени работы программы. Так что думайте, что выбрать! Макроопределение создает "строчный" код, т. е. вы получаете оператор в программе. Если макроопределение применить 20 раз, то в вашу программу вставится 20 строк кода. Если вы используете функцию 20 раз, у вас будет только одна копия операторов функции, поэтому получается меньший объем памяти. Однако управление программой следует передать туда, где находится функция, а затем вернуться в вызывающую программу, а на это потребуется больше времени, чем при работе со "строчными" кодами.

Преимущество макроопределений заключается в том, что при их использовании вам не нужно беспокоиться о типах переменных (макроопределения имеют дело с символьными строками, а не с фактическими значениями). Так наше макроопределение SQUARE(x) можно использовать одинаково хорошо с переменными типа int или float.

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

#define MAX(X,Y) ( (X) > (Y) ? (X) : (Y))

#define ABS(X) ( (X) < 0 ?
– (X) : (X))

#define ISSIGN(X) ( (X) == '+' || (X) == '-' ? 1 : 0)

(Последнее макроопределение имеет значение 1 (истинно), если X является символом алгебраического знака.) Отметим следующие моменты:

1. В макроопределении нет пробелов, но они могут появиться в замещающей строке. Препроцессор "полагает", что макроопределение заканчивается на первом пробеле, поэтому все, что стоит после пробела, остается в замещающей строке.

РИС. 11.2. Ошибочный пробел и макроопределении.

2. Используйте круглые скобки для каждого аргумента и всего определения. Это является гарантией того, что элементы будут сгруппированы надлежащим образом в выражении, подобном forks = 2*MAX(guests + 3, last);

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

  • Читать дальше
  • 1
  • ...
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: