C — Препроцессоры
Препроцессор C не является частью компилятора, а представляет собой отдельный шаг в процессе компиляции. Проще говоря, препроцессор C — это просто инструмент подстановки текста, который указывает компилятору выполнить необходимую предварительную обработку перед фактической компиляцией. Мы будем называть препроцессор C CPP.
Все команды препроцессора начинаются с символа решетки (#). Это должен быть первый непустой символ, и для удобочитаемости директива препроцессора должна начинаться с первого столбца. В следующем разделе перечислены все важные директивы препроцессора —
Сер.№ | Директива и описание |
---|---|
1 | <тд>|
2 | <тд>|
3 | <тд>|
4 | <тд>|
5 | <тд>|
6 | <тд>|
7 | <тд>|
8 | <тд>|
9 | <тд>|
10 | <тд>|
11 | <тд>
Примеры препроцессоров
Проанализируйте следующие примеры, чтобы понять различные директивы.
#define MAX_ARRAY_LENGTH 20
Эта директива указывает CPP заменить экземпляры MAX_ARRAY_LENGTH на 20. Используйте #define для констант для повышения удобочитаемости.
#include <stdio.h> #include "myheader.h"
Эти директивы указывают CPP получить stdio.h из системных библиотек. и добавьте текст в текущий исходный файл. Следующая строка указывает CPP получить myheader.h из локального каталога и добавить содержимое в текущий исходный файл.
#undef FILE_SIZE #define FILE_SIZE 42
Он сообщает CPP отменить определение существующего FILE_SIZE и определить его как 42.
#ifndef MESSAGE #define MESSAGE "You wish!" #endif
Он указывает CPP определять MESSAGE только в том случае, если MESSAGE еще не определено.
#ifdef DEBUG /* Your debugging statements here */ #endif
Он сообщает CPP обработать вложенные операторы, если определено DEBUG. Это полезно, если вы передаете -DDEBUG флаг компилятору gcc во время компиляции. Это определит DEBUG, так что вы сможете включать и выключать отладку на лету во время компиляции.
Предопределенные макросы
ANSI C определяет ряд макросов. Хотя каждый из них доступен для использования в программировании, предопределенные макросы нельзя изменять напрямую.
Сер.№ | Макрос и описание |
---|---|
1 | <тд>|
2 | <тд>|
3 | <тд>|
4 | <тд>|
5 | <тд>
Давайте попробуем следующий пример —
Живая демонстрация#include <stdio.h> int main() { printf("File :%s\n", __FILE__ ); printf("Date :%s\n", __DATE__ ); printf("Time :%s\n", __TIME__ ); printf("Line :%d\n", __LINE__ ); printf("ANSI :%d\n", __STDC__ ); }
Когда приведенный выше код в файле test.c компилируется и выполняется, он дает следующий результат —
File :test.c Date :Jun 2 2012 Time :03:36:24 Line :8 ANSI :1
Операторы препроцессора
Препроцессор C предлагает следующие операторы для создания макросов —
Оператор продолжения макроса (\)
Макрос обычно ограничивается одной строкой. Оператор продолжения макроса (\) используется для продолжения макроса, который слишком длинный для одной строки. Например —
#define message_for(a, b) \ printf(#a " and " #b ": We love you!\n")
Оператор строки (#)
Оператор stringize или числового знака ( '#' ) при использовании в определении макроса преобразует параметр макроса в строковую константу. Этот оператор может использоваться только в макросе, имеющем указанный аргумент или список параметров. Например —
Живая демонстрация#include <stdio.h> #define message_for(a, b) \ printf(#a " and " #b ": We love you!\n") int main(void) { message_for(Carole, Debra); return 0; }
Когда приведенный выше код скомпилирован и выполнен, он дает следующий результат —
Carole and Debra: We love you!
Оператор вставки токена (##)
Оператор вставки токена (##) в определении макроса объединяет два аргумента. Он позволяет объединить два отдельных токена в определении макроса в один токен. Например —
Живая демонстрация#include <stdio.h> #define tokenpaster(n) printf ("token" #n " = %d", token##n) int main(void) { int token34 = 40; tokenpaster(34); return 0; }
Когда приведенный выше код скомпилирован и выполнен, он дает следующий результат —
token34 = 40
Это произошло потому, что этот пример приводит к следующему фактическому выводу препроцессора —
printf ("token34 = %d", token34);
В этом примере показано объединение token##n в token34, и здесь мы использовали как stringize и вставка токена .
Оператор Defined()
Препроцессор определен оператор используется в постоянных выражениях, чтобы определить, определен ли идентификатор с помощью #define. Если указанный идентификатор определен, значение равно true (не ноль). Если символ не определен, значение равно false (ноль). Определенный оператор указывается следующим образом —
Живая демонстрация#include <stdio.h> #if !defined (MESSAGE) #define MESSAGE "You wish!" #endif int main(void) { printf("Here is the message: %s\n", MESSAGE); return 0; }
Когда приведенный выше код скомпилирован и выполнен, он дает следующий результат —
Here is the message: You wish!
Макросы с параметрами
Одной из мощных функций CPP является возможность имитации функций с помощью параметризованных макросов. Например, у нас может быть некоторый код для возведения числа в квадрат следующим образом —
int square(int x) { return x * x; }
Мы можем переписать приведенный выше код с помощью макроса следующим образом —
#define square(x) ((x) * (x))
Макросы с аргументами должны быть определены с помощью команды #define. директивы, прежде чем они могут быть использованы. Список аргументов заключен в круглые скобки и должен следовать сразу за именем макроса. Пробелы между именем макроса и открывающей скобкой не допускаются. Например —
Живая демонстрация#include <stdio.h> #define MAX(x,y) ((x) > (y) ? (x) : (y)) int main(void) { printf("Max between 20 and 10 is %d\n", MAX(10, 20)); return 0; }
Когда приведенный выше код скомпилирован и выполнен, он дает следующий результат —
Max between 20 and 10 is 20
Язык C
- C# Hello World — ваша первая программа на C#
- Ключевые слова и идентификаторы C#
- Переменные C# и (примитивные) типы данных
- Операторы С#
- Побитовые операторы C# и операторы сдвига битов
- Базовый ввод и вывод C#
- Выражения, операторы и блоки C# (с примерами)
- С# Комментарии
- Оператор переключения C#
- С# тернарный (?:) оператор