Препроцессор языка “C”

Язык С
Учебное введение Оператор FOR Копирование файла Подсчет строк Массивы Аргументы - вызов по значению Область действия: внешние переменные Резюме Константы Арифметические операции Затем, если один из операндов имеет тип DOUBLE, то другой преобразуется в DOUBLE, и результат имеет тип DOUBLE Побитовые логические операции Условные выражения Поток управления Переключатель Цикл DO - WHILE Оператор GOTO и метки Функции, возвращающие нецелые значения Внешние переменные Правила, определяющие область действия Статические переменные Инициализация Препроцессор языка “C” Указатели и адреса Адресная арифметика Указатели символов и функции Многомерные массивы Инициализация массивов указателей Структуры Массивы сруктур Указатели на структуры Поиск в таблице Объединения Ввод и вывод Средства ввода/вывода не являются составной частью языка “с”, так что мы не выделяли их в нашем предыдущем изложении Форматный вывод - функция PRINTF Обычные символы (не %), которые предполагаются совпадающими со следующими отличными от символов пустых промежутков символами входного потока Форматное преобразование в памяти Низкоуровневый ввод/вывод - операторы READ и WRITE Произвольный доступ - SEEK и LSEEK Пример - распределитель памяти Лексические соглашения Имеется шесть классов лексем: идентификаторы, ключевые слова, константы, строки, операции и другие разделители Характеристики аппаратных средств Следующая ниже таблица суммирует некоторые свойства аппаратного оборудования, которые меняются от машины к машине Первичные выражения Первичные выражения, включающие ., ->, индексацию и обращения к функциям, группируются слева направо Унарные операции Выражение с унарными операциями группируется справо налево Операции равенства Выражение-равенства: выражение == выражение выражение != выражение Операция запятая Выражение-с-запятой: выражение , выражение Внешние определения данных Снова о типах В этом разделе обобщаются сведения об операциях, которые можно применять только к объектам определенных типов Анахронизмы Так как язык “C” является развивающимся языком, в старых программах можно встретить некоторые устаревшие конструкции
424070
знаков
0
таблиц
0
изображений

4.11. Препроцессор языка “C”.

В языке “с” предусмотрены определенные расширения языка с помощью простого макропредпроцессора. одним из самых распространенных таких расширений, которое мы уже использовали, является конструкция #DEFINE; другим расширением является возможность включать во время компиляции содержимое других файлов.

4.11.1. Включение файлов

Для облегчения работы с наборами конструкций #DEFINE и описаний (среди прочих средств) в языке “с” предусмотрена возможность включения файлов. Любая строка вида

#INCLUDE “FILENAME” заменяется содержимым файла с именем FILENAME. (Кавычки обязательны). Часто одна или две строки такого вида появляются в начале каждого исходного файла, для того чтобы включить общие конструкции #DEFINE и описания EXTERN для глобальных переменных. Допускается вложенность конструкций #INCLUDE.

Конструкция #INCLUDE является предпочтительным способом связи описаний в больших программах. Этот способ гарантирует, что все исходные файлы будут снабжены одинаковыми определениями и описаниями переменных, и, следовательно, исключает особенно неприятный сорт ошибок. Естественно, когда какой-TO включаемый файл изменяется, все зависящие от него файлы должны быть перекомпилированы.

4.11.2. Макроподстановка

Определение вида #DEFINE TES 1 приводит к макроподстановке самого простого вида - замене имени на строку символов. Имена в #DEFINE имеют ту же самую форму, что и идентификаторы в “с”; заменяющий текст совершенно произволен. Нормально заменяющим текстом является остальная часть строки; длинное определение можно продолжить, поместив в конец продолжаемой строки. “Область действия” имени, определенного в #DEFINE, простирается от точки определения до конца исходного файла. имена могут быть переопределены, и определения могут использовать определения, сделанные ранее. Внутри заключенных в кавычки строк подстановки не производятся, так что если, например, YES - определенное имя, то в PRINTF(“YES”) не будет сделано никакой подстановки.

Так как реализация #DEFINE является частью работы маKропредпроцессора, а не собственно компилятора, имеется очень мало грамматических ограничений на то, что может быть определено. Так, например, любители алгола могут объявить

#DEFINE THEN #DEFINE BEGIN { #DEFINE END ;}

и затем написать IF (I > 0) THEN BEGIN A = 1;

B = 2 END Имеется также возможность определения макроса с аргументами, так что заменяющий текст будет зависеть от вида обращения к макросу. Определим, например, макрос с именем MAX следующим образом:

#DEFINE MAX(A, B) ((A) > (B) ? (A) : (B)) когда строка X = MAX(P+Q, R+S);

будет заменена строкой X = ((P+Q) > (R+S) ? (P+Q) : (R+S));

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

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

#DEFINE SQUARE(X) X * X при обращении к ней, как SQUARE(Z+1)). Здесь возникают даже некоторые чисто лексические проблемы: между именем макро и левой круглой скобкой, открывающей список ее аргументов, не должно быть никаких пробелов.

Тем не менее аппарат макросов является весьма ценным.

Один практический пример дает описываемая в главе 7 стандартная библиотека ввода-вывода, в которой GETCHAR и PUTCHAR определены как макросы (очевидно PUTCHAR должна иметь аргумент), что позволяет избежать затрат на обращение к функции при обработке каждого символа.

Другие возможности макропроцессора описаны в приложении А.

Упражнение 4-9.

Определите макрос SWAP(X, Y), который обменивает значениями два своих аргумента типа INT. (В этом случае поможет блочная структура).

98

5.Указатели и массивы Указатель - это переменная, содержащая адрес другой переменной. указатели очень широко используются в языке “C”.

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

Указатели обычно смешивают в одну кучу с операторами GOTO, характеризуя их как чудесный способ написания программ, которые невозможно понять. Это безусловно спрAведливо, если указатели используются беззаботно; очень просто ввести указатели, которые указывают на что-то совершенно неожиданное. Однако, при определенной дисциплине, использование указателей помогает достичь ясности и простоты. Именно этот аспект мы попытаемся здесь проиллюстрировать.


Информация о работе «Язык С»
Раздел: Информатика, программирование
Количество знаков с пробелами: 424070
Количество таблиц: 0
Количество изображений: 0

Похожие работы

Скачать
48443
0
0

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

Скачать
43709
0
0

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

Скачать
39778
0
1

... рисуночное словесно-слоговое письмо). Памятники среднеэламского периода (14—12 вв. до н.э.) выполнены аккадской клинописью. Памятники новоэламского периода относятся к 8—6 вв. до н.э. Был официальным языком в персидском государстве Ахеменидов в 6—4 вв. предполагается, что он, подвергшись влиянию древнеперсидского, сохранился до раннего средневековья. 7. Бурушаски язык Язык бурушаски ( ...

Скачать
64931
0
0

... /диалект), скифский, согдийский, среднеперсидский, таджикский, таджриши (язык/диалект), талышский, татский, хорезмийский, хотаносакский, шугнано-рушанская группа языков, ягнобский, язгулямский и др. Они относятся к индоиранской ветви индоевропейских языков. Области распространения: Иран, Афганистан, Таджикистан, некоторые районы Ирака, Турции, Пакистана, Индии, Грузии, Российской Федерации. Общее ...

0 комментариев


Наверх