Array M. УЭИТ - Язык Си - руководство для начинающих
- Название:Язык Си - руководство для начинающих
- Автор:
- Жанр:
- Издательство:Мир
- Год:1988
- Город:Москва
- ISBN:5-03-001309-1 /русск./
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Array M. УЭИТ - Язык Си - руководство для начинающих краткое содержание
Язык Си — руководство для начинающих
Язык Си - руководство для начинающих - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
РИС. 11.1. Части макроопределения.
т. е. слово TWOзаменилось цифрой 2. Затем оператор РХ;превращается в printf("X равно %d. \n", х);поскольку сделана полная замена. Это новшество, так как до сих пор мы использовали макроопределения только для представления констант. Теперь же мы видим, что макроопределение может представлять любую строку, даже целое выражение на языке Си. Заметим, однако, что это константная строка; РХнапечатает только переменную, названную x.
Следующая строка также представляет что-то новое. Вы можете подумать, что FOURзаменяется на 4, но на самом деле выполняется следующее:
х = FOUR;
превращается в х = TWO *TWO;превращается в х = 2*2;и на этом все заканчивается. Фактическое умножение имеет место не во время работы препроцессора и не при компиляции, а всегда без исключения при работе программы. Препроцессор не выполняет вычислений; он только очень точно делает предложенные подстановки.
Заметим, что макроопределение может включать другие определения. (Некоторые компиляторы не поддерживают это свойство "вложения".)
В следующей строке printf(FMT, х);превращается в printf(" Х равно %d.\n", х)когда FMTзаменяется соответствующей строкой. Этот подход может оказаться очень удобным, если у вас есть длинная строка, которую вы используете несколько раз.
В следующей строке программы MSGзаменяется соответствующей строкой. Кавычки делают замещающую строку константой символьной строки; поскольку программа получает ее содержимое, эта строка будет запоминаться в массиве, заканчивающемся нуль-символом. Так, #define HAL 'Z'определяет символьную константу, а #define НАР "Z"определяет символьную строку: Z\0.
Обычно препроцессор, встречая одно из ваших макроопределений в программе, очень точно заменяет их эквивалентной строкой замещения. Если эта строка также содержит макроопределения, они тоже замешаются. Единственным исключением при замене является макроопределение, находящееся внутри двойных кавычек. Поэтому printf("TWO: MSG");печатает буквально TWO: MSGвместо печати следующей строки:
2: "Старый серый кот поет веселую песню."
Если вам нужно напечатать эту строку, можно использовать оператор
printf("%d: %s\n", TWO, MSG);
потому что здесь макроопределения находятся вне кавычек.
Когда следует использовать символические константы? Вероятно, вы должны применять их для большинства чисел. Если число является константой, используемой в вычислениях, то символическое имя делает яснее ее смысл. Если число - размер массива, то символическое имя упрощает изменение вашей программы при работе с большим массивом. Если число является системным кодом, скажем для символа EOF, то символическое представление делает вашу программу более переносимой; изменяется только определение EOF. Мнемоническое значение, легкость изменения, переносимость: все это делает символические константы заслуживающими внимания. Легко ли этого достичь? Рискнем и рассмотрим простую функцию, т. е. макроопределение с аргументами.
ИСПОЛЬЗОВАНИЕ АРГУМЕНТОВ С #define
Макроопределение с аргументами очень похоже на функцию, поскольку аргументы его заключены в скобки. Ниже приведено несколько примеров, иллюстрирующих, как определяется и используется такая "макрофункция". В некоторых примерах к тому же указаны возможные ловушки, поэтому читайте их внимательно.
/* макроопределение с аргументами */
#define SQUARE (х) х*х
#define PR(x) printf("x равен %d.\n" ,x)
main( )
{
int x = 4;
int z;
z = SQUARE(x);
PR(z);
z = SQUARE(2);
PR(z);
PR(SQUARE(x));
PR(SQUARE(x + 2));
PR(100/SQUARE(2));
PR(SQUAREC(++x));
}
Всюду, где в вашей программе появляется макроопределение SQUARE(x), оно заменяется на х*х. В отличие от наших прежних примеров при использовании этого макроопределения мы можем совершенно свободно применять символы, отличные от x. В макроопределении 'x'замещается символом, использованным в макровызове программы. Поэтому макроопределение SQUARE(2)замещается на 2*2. Таким образом, xна самом деле действует как аргумент. Однако, как вы вскоре увидите, аргумент макроопределения не "работает" точно так же, как аргумент функции. Вот результаты выполнения программы. Обратите внимание, что некоторые ответы отличаются от тех, которые вы могли бы ожидать.
z paвнo 16.
z paвнo 4.
SQUARE(x) равно 16.
SQUARE(x + 2) равно 14.
100/SQUARE(2) равно 100.
SQUAREC(++ x) равно 30.
Первые две строки предсказуемы. Заметим, однако, что даже внутри двойных кавычек в определении PRпеременная замещается соответствующим аргументом. Все аргументы в этом определении замещаются.
Третья строка представляет интерес:
PR(SQUARE(x));
она становится следующей строкой:
printf("SQUARE(x) равно %d.\n", SQUARE(x));
после первого этапа макрорасширения. Второе SQUARE(x)расширяется, превращаясь в х*х, а первое остается без изменения, потому что теперь оно находится внутри двойных кавычек в операторе программы, и таким образом защищено от дальнейшего расширения. Окончательно строка программы содержит
printf(" SQUARE(x) равно %d.\n", x*x);
и выводит на печать
SQUARE(x) равно 16.
при работе программы.
Давайте еще раз проверим то, что заключено в двойные кавычки. Если ваше макроопределение включает аргумент с двойными кавычками, то аргумент будет замещаться строкой из макровызова. Но после этого он в дальнейшем не расширяется, даже если строка является еще одним макроопределением. В нашем примере переменная хстала макроопределением SQUARE(x)и осталась им.
Теперь мы добрались до несколько специфических результатов. Вспомним, что химеет значение b. Это позволяет предположить, что SQUARE(x + 2)будет равно 6*6или 36. Но напечатанный результат говорит, что получается число 14, которое, несомненно, никак не похоже на квадрат целого числа! Причина такого вводящего в заблуждение результата проста, и мы уже об этом говорили: препроцессор не делает вычислений, он только замещает строку. Всюду, где наше определение указывает на х, препроцессор подставит строку х + 2. Таким образом, х*хстановится х + 2*х + 2.
Единственное умножение здесь 2*x. Если xравно 4, то получается следующее значение этого выражения:
Читать дальшеИнтервал:
Закладка: