C Language: #define Directive (macro definition)
This C tutorial explains how to use the #define preprocessor directive in the C language.
Description
In the C Programming Language, the #define directive allows the definition of macros within your source code. These macro definitions allow constant values to be declared for use throughout your code.
Macro definitions are not variables and cannot be changed by your program code like variables. You generally use this syntax when creating constants that represent numbers, strings or expressions.
Syntax
The syntax for creating a constant using #define in the C language is:
#define CNAME value
#define CNAME (expression)
CNAME The name of the constant. Most C programmers define their constant names in uppercase, but it is not a requirement of the C Language. value The value of the constant. expression Expression whose value is assigned to the constant. The expression must be enclosed in parentheses if it contains operators.
Note
- Do NOT put a semicolon character at the end of #define statements. This is a common mistake.
Example
Let’s look at how to use #define directives with numbers, strings, and expressions.
Number
The following is an example of how you use the #define directive to define a numeric constant:
#define AGE 10
In this example, the constant named AGE would contain the value of 10.
String
You can use the #define directive to define a string constant.
#define NAME "TechOnTheNet.com"
In this example, the constant called NAME would contain the value of «TechOnTheNet.com».
Below is an example C program where we define these two constants:
#include #define NAME «TechOnTheNet.com» #define AGE 10 int main()
This C program would print the following:
TechOnTheNet.com is over 10 years old.
Expression
You can use the #define directive to define a constant using an expression.
#define AGE (20 / 2)
In this example, the constant named AGE would also contain the value of 10.
Below is an example C program where we use an expression to define the constant:
#include #define AGE (20 / 2) int main()
This C program would also print the following:
TechOnTheNet.com is over 10 years old.
#define
Директива #define определяет идентификатор и последовательность символов, которой будет замещаться данный идентификатор при его обнаружении в тексте программы. Идентификатор также называется именем макроса, а процесс замещения называется подстановкой макроса. Стандартный вид директивы следующий:
#define имя_макроса последовательность_символов
Обратим внимание, что в данном операторе отсутствует точка с запятой. Между идентификатором и последовательностью символов может быть любое число пробелов. Макрос завершается только переходом на новую строку.
Например, если необходимо использовать TRUE для значения 1, a FALSE для 0 то можно объявить следующие два макроса:
#define TRUE 1
#define FALSE 0
В результате, если компилятор обнаружит в тексте программы TRUE или FALSE, то он заменит их на 1 и 0 соответственно. Например, следующая строка выводит на экран «0 1 2»:
printf («%d %d %d», FALSE, TRUE, TRUE + 1);
В случае, если макрос определен, он может использоваться для определения других макросов. Например, следующий код сопоставляет с именами ONE, TWO и THREE их численные значения:
#define ONE 1
#define TWO ONE + ONE
#def ine THREE ONE + TWO
В результате макроподстановки идентификаторы замещаются указанными строками. Если необходимо определить стандартное сообщение об ошибке, то можно написать что-то вроде следующего:
#define E_MS «Standart error on input.\n»
/*. */
printf(E_MS);
Если компилятор обнаруживает идентификатор E_MS, то он замещает его строкой «Standart error on input.» На самом деле компилятор увидит оператор в виде
printf(«Standart error on input.\n»);
Если идентификатор находится в строке, то подстановка не происходит. Например:
#define XYZ this is a test
/*. */
printf(«XYZ»);
выведет не «this is a test», a «XYZ».
Если строка не вмещается в одной строке, то ее можно продолжить на следующей строке, поместив в конце строки обратный слэш, как показано в следующем примере:
#define LONG_STRING «This is a very long» \
string that is used as an example.»
Программисты, пишущие на С, часто используют заглавные буквы для определения идентификаторов. Данное соглашение помогает любому человеку, читающему программу, бросив на нее один взгляд, узнать, что он имеет дело с макросом. Также вce #define лучше помещать в начале файла или вообще в отдельный заголовочный файл.
Очень часто макросы используют для определения «магических чисел», используемых в программе. Например, программа может определять массив и иметь несколько процедур для работы с ним. Вместо того, чтобы жестко кодировать размер массива, лучше определить макрос, соответствующий размеру массива, и использовать его в тех местах, где необходимо использование размера. Таким образом, если необходимо изменить размер массива, единственное, что требуется сделать, — это изменить оператор #define и перекомпилировать программу. Везде, где использовался данный макрос, произойдут автоматические изменения. Рассмотрим пример:
#define MAX_SIZE 100
/*. */
float balance[MAX_SIZE];
/*. */
float temp[MAX_SIZE];
Для изменения размеров обоих массивов просто изменим определение MAX_SIZE.
Директива #define имеет еще одну возможность: макрос может иметь аргументы. Каждый раз при встрече такого макроса аргументы макроса будут замещаться реальными аргументами программы. Такой тип макроса называется макрос типа функция. Например:
#include
#define MIN(a,b) ((a) <(b)) ? (a) : (b)
int main(void)
int x, y;
x = 10; у = 20;
printf(«The minimum is: %d», MIN(x, y) );
return 0;
>
При компиляции программы вместо MIN(a, b) подставляется указанное выражение, причем вместо фиктивных параметров а и b подставляются реальные х и у. Таким образом, в результате подстановки функция printf() примет следующий вид:
Надо быть осторожным при определении макросов, получающих аргументы, или можно получить несколько неожиданные результаты. Например, рассмотрим следующую короткую программу, использующую макрос для определения четности значения:
/* программа выдает неправильный результат */
#include
#define EVEN(a) a%2==0 ? 1 : 0
int main(void)
if (EVEN(9+1) ) printf(«is even»);
else printf («is odd»);
return 0;
>
Из-за способа подстановки данная программа работает неправильно. В результате компиляции программы EVEN(9 + 1) расширится до
9 + 1% 2 == 0 ? 1 : 0
Как известно, оператор взятия по модулю имеет более высокий приоритет, чем оператор сложения. Это означает, что сначала выполнится взятие по модулю с числом 1, а затем результат прибавится к 9, что, естественно, не может быть равно 0. Для устранения данной проблемы следует заключить а в макросе EVEN в круглые скобки, как показано в следующей правильной версии программы:
#include
#define EVEN(a) (a)%2==0 ? 1 : 0
int main(void)
if(EVEN(9 + 1) ) printf(«is even»);
else printf(«is odd»);
return 0;
>
Обратим внимание, что 9+1 вычисляется до взятия по модулю. В целом заключение параметров макроса в скобки — это достаточно хорошая идея, и она позволяет избежать множества проблем.
Использование макроподстановок вместо реальных функций имеет одно большое преимущество — существенно увеличивается скорость работы программы, поскольку нет необходимости тратить время на вызов функции и возврат из нее. Тем не менее, за данное увеличение скорости работы следует платить увеличением размера исполнимого кода программы, поскольку программа вынуждена дублировать код макроса.
C define как в c
The special operator defined is used in ‘ #if ’ and ‘ #elif ’ expressions to test whether a certain name is defined as a macro. defined name and defined ( name ) are both expressions whose value is 1 if name is defined as a macro at the current point in the program, and 0 otherwise. Thus, #if defined MACRO is precisely equivalent to #ifdef MACRO .
defined is useful when you wish to test more than one macro for existence at once. For example,
#if defined (__vax__) || defined (__ns16000__)
would succeed if either of the names __vax__ or __ns16000__ is defined as a macro.
Conditionals written like this:
#if defined BUFSIZE && BUFSIZE >= 1024
can generally be simplified to just #if BUFSIZE >= 1024 , since if BUFSIZE is not defined, it will be interpreted as having the value zero.
If the defined operator appears as a result of a macro expansion, the C standard says the behavior is undefined. GNU cpp treats it as a genuine defined operator and evaluates it normally. It will warn wherever your code uses this feature if you use the command-line option -Wpedantic , since other compilers may handle it differently. The warning is also enabled by -Wextra , and can also be enabled individually with -Wexpansion-to-defined .
C define как в c
A macro is a fragment of code which has been given a name. Whenever the name is used, it is replaced by the contents of the macro. There are two kinds of macros. They differ mostly in what they look like when they are used. Object-like macros resemble data objects when used, function-like macros resemble function calls.
You may define any valid identifier as a macro, even if it is a C keyword. The preprocessor does not know anything about keywords. This can be useful if you wish to hide a keyword such as const from an older compiler that does not understand it. However, the preprocessor operator defined (see Defined) can never be defined as a macro, and C++’s named operators (see C++ Named Operators) cannot be macros when you are compiling C++.
- Object-like Macros
- Function-like Macros
- Macro Arguments
- Stringizing
- Concatenation
- Variadic Macros
- Predefined Macros
- Undefining and Redefining Macros
- Directives Within Macro Arguments
- Macro Pitfalls