- •Рецензенты:
- •Лекция 1 Основные понятия языка с
- •Первая программа
- •Переменные языка с
- •Имя переменной
- •Объявление константы
- •Операции языка с
- •Лекция 2 Операторы языка с Условный оператор
- •Оператор switch
- •Циклы Цикл for
- •Циклы while и do-while
- •Оператор безусловного перехода
- •Использование операторов break, continue и goto в циклах
- •Операция условие ?
- •Лекция 3 Массивы
- •Инициализация массивов
- •Массивы символов. Строки
- •Функции для работы со строками
- •Лекция 4 Указатели
- •Объявление указателей
- •Операции над указателями
- •Связь указателей и массивов
- •Массивы указателей
- •Инициализация указателей
- •Лекция 5 Функции языка с
- •Объявление функции
- •Оператор return
- •Прототипы функций
- •Функции c произвольным числом параметров
- •Область действия и область видимости переменной
- •Классы памяти
- •Параметры и аргументы функции
- •Лекция 6 Типы, определяемые пользователями
- •Структура
- •Перечислимый тип
- •Переименование типов-typedef
- •Лекция 7 Модели памяти и препроцессор языка с Модели памяти
- •Препроцессор языка с
- •Директива #define
- •Список рекомендуемой литературы
- •Оглавление
- •Программирование на языках высокого уровня: с
- •428015 Г.Чебоксары, Московский просп., 15
Препроцессор языка с
Препроцессор языка С - это программа, выполняющая обработку входных данных для другой программы. Препроцессор языка С просматривает программу до компилятора, заменяет аббревиатуры в тексте программы на соответствующие директивы, отыскивает и подключает необходимые файлы, может влиять на условия компиляции. Директивы препроцессора языка С в действительности не являются частью языка С. Препроцессор включает в себя следующие директивы:
#define |
Определение макроса |
#undef |
Отмена определения макроса |
#include |
Включение объекта-заголовка |
#if |
Компиляция, если выражение истинно |
#ifdef |
Компиляция, если макрос определен |
#ifndef |
Компиляция, если макрос не определен |
#else |
Компиляция, если выражение в if ложно |
#elif |
Составная директива else/if |
#endif |
Окончание группы компиляции по условию |
: #line |
Замена новым значением номера строки или имени исходного файла |
#еггог |
Формирование ошибок трансляции |
#pragma |
Действие определяется реализацией |
# |
null-директива |
## |
Склеивание лексем |
# |
Придание операнду формы строки символов |
#defined |
Представление #ifdef в форме выражения |
Все директивы препроцессора начинаются с символа #.
Директива #define
Директива #define вводит макроопределение или макрос. Общая форма директивы следующая:
#define имя_макроса последовательность_символов
Последовательность символов называют еще строкой замещения. Когда препроцессор находит в исходном тексте программы имя_макроса (в дальнейшем будем говорить просто макрос), он заменяет его на последовательность символов. Любые вхождения макроса, обнаруженные в строках символов, символьных константах или в комментариях, замене не подлежат. Можно отменить определение макроса директивой #undef: #undef имя_макроса
Данная строка удаляет любую ранее введенную строку замещения. Определение макроса теряется, и имя_макроса становится неопределенным.
К примеру можно определить МАХ как величину равную 100:
#define MAX 100
Это значение будет подставляться каждый раз вместо макроса мах в исходном файле. Можно также использовать макрос вместо строковой константы:
# define NAME "Turbo C++ v. 1.01"
Если последовательность символов в директиве #define не помещается на одной строке, то можно поставить в конце строки символ \ и продолжать последовательность на другой строке:
#define STRING "Эта последовательность символов не \
умещается на одной строке, мы используем две"
Среди программистов на языке С принято соглашение, что для имени макроса используются, как правило, идентификаторы из прописных букв. Это соглашение позволяет легко находить в тексте программы макросы. Также лучше все директивы #define выносить в начало файла или в отдельный заголовочный файл.
Наиболее часто директива #define используется для определения имени "магических чисел", которые встречаются в программе. Например, если вы задаете один размер массивов в программе и в некоторых подпрограммах используете массивы того же размера, то предпочтительно определить размер массива директивой #define и использовать в объявлениях массивов этот макрос. Например:
#define MAX 100 float balance[MAX], saldo|MAX];
Директива #define имеет еще одну важную особенность: макрос может иметь аргументы. Каждый раз, когда происходит замена, аргументы также заменяются на те, которые встречаются в программе. Иллюстрацией может служить следующий пример:
#define MIN(a.b) ((a)<(b))?(a):(b)
printf( "Минимум из х и у %d", MIN(x,y));
printf("Минимум из а и b %d", MIN(m,n));
Когда программа будет компилироваться, в выражение, определенное МIN(а, b), будут подставлены соответственно х и у или m и n. Аргументы а и b заключены в круглые скобки, так как вместо них может подставляться некоторое выражение, а не просто идентификаторы, например,
printf ("Минимум %d".MIN(x*x,x*x*x));
Директива #/error имеет вид
#error сообщение _об_ошибке
Эта директива прекращает компиляцию программы и выдает сообщение
Error: имя _файла номер_строки: error directive:
сообщение об ошибке
Сообщение об ошибке не заключается в кавычки. Данная директива обычно встраивается в условные конструкции препроцессора.
Директива #include подключает к исходному коду заданные в директиве файлы. Эти файлы называются подключаемыми, заголовочными файлами, заголовками.
Часто в качестве подключаемых файлов используются заголовочные файлы библиотек языка С. Форма этой директивы может быть следующих видов:
#nclude <имя_заголовка>,
#include "имя заголовка",
#include имя макроса
Tpeтья форма директивы предполагает, что первым символом после пробела не будут символы < или "; кроме того, предполагается, что существует макроопределение, которое заменит имя макроса либо на <имя заголовка>, либо на "имя_заголовка".
Имя заголовка должно быть допустимым именем файла DOS с расширением (традиционно заголовочные файлы имеют расширение .h, в языке C++ иногда встречается hpр). Различие между форматами <имя_заголовка> и "имя заголовка" состоит в алгоритме поиска подключаемого файла. Вариант <имя заголовка> задает стандартный включаемый файл. Поиск, следовательно, производится во всех включаемых директориях в той последовательности, в которой они определены. Если ни в одной из этих директорий файл не найден, то выдается сообщение об ошибке. Вариант "имя заголовка" задает включаемый файл, созданный пользователем. Сначала он ищется в текущей директории, а если там не найден, то поиск продолжается во всех включаемых директориях так же, как и в первом случае.
