Summary
1) #define
is one of the unit entities processed by the preprocessor
text replacement is performed during the pre-compilation period
2) #define
can appear anywhere in the program , and the code after the definition can be used
3) #define
can define macro constants, which are essentially literals
4) define
can define an expression, use the similar function ; function
may be more powerful (type can be used as a parameter, find the size of the array);
more error-prone (when mixed with other operations)
5) Since the macro is a direct text replacement, does not have any call overhead
cannot be recursive in the macro expression; the macro is processed by the preprocessor, so the
compiler does not know the existence of the macro, and naturally, the
macro does not have any The concept of
scope is for variables and functions.
6) Commonly used predefined macros
Macro | meaning | Example |
__FILE__ | File name to be compiled | file1.c |
__LINE__ | Current line number | 25 |
__DATE__ | Compile date | Jan 31 2012 |
__TIME__ | Compile time | 17:01:01 |
__STDC__ | Does the compiler follow the standard C specification | 1 |
Macro definition and usage analysis
#define
is one of the unit entities processed by the preprocessor
#define
can appear anywhere in the program
The code after the definition of #define
1. Macro constants defined by #define
#define
can be used directly, the essence is literal (will not occupy memory, string literal will be stored in read-only storage area)
// test.c中 下面的宏定义正确么?
#define ERROR -1
#define PATH1 "D:\test\test.c"
#define PATH2 D:\test\test.c
#define PATH3 D:\test\
test.c
int main()
{
int i = ERROR;
char* p1 = PATH1;
char* p2 = PATH2;
char* p3 = PATH3;
return 0;
}
单步编译
gcc -E test.c -o test.i ==> 预编译,生成中间文件.i
gcc -S test.i -o test.s ==> 编译,生成汇编文件.s
Analysis: In the first pre-compilation stage, the define is processed and the .i file is generated. There will be no error at this time; in the next compilation stage, when the intermediate file is converted to an assembly file, an error will be reported.
The reason is: in the , only text replacement is performed, without syntax checking; when the
compile stage, the grammar check is performed on the replaced .i file, and then the assembly file is generated. At this time, the syntax check is wrong.
2. #define defined expression
#define
expressions similar function calls
#define
expressions can be more powerful than functions
#define
Expressions are more error-prone than functions
#define SUM(a, b) (a) + (b)
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define DIM(a) sizeof(a) / sizeof(*a)
int main()
{
int a = 1;
int b = 3;
int c[2] = {0};
// expected: 4, 1, 2
printf("SUM(a, b) = %d\n", SUM(a, b));
printf("MIN(a, b) = %d\n", MIN(a, b));
printf("size of array = %d\n", DIM(c));
// unexpected: 3
printf("unexpected: %d", MIN(++a, b)); // 期望得到++a和b中的较小的值:2
return 0;
}
analyze:
- The define expression
similar to a function call. Like the above example, the definition of a macro in printf is very much like a function call.
- The define expression may be
more powerful than the function. As above, the
DIM macro can find the size of the array,
cannot find the size of an array through the function in the C language, because
degenerates into a pointer when the array is used as a function parameter. ; For another example,
C language cannot take type as a parameter, but macros can.
- The define expression
more error-prone. As above, the expected value of MIN(++a, b) is 2, but the actual value is 3. From the result of single-step compilation, it can be seen that the expression after replacement is
((++a) < (b) ? (++b) : (b))
, and the preceding ++ is executed twice, so 3 is obtained.pre-compiler is like a microphone. In the process of transmitting, there is ambiguity.
The macro expression is preprocessor, and the compiler does not know the existence of the macro;
Macro expressions use "actual parameters" to completely replace formal parameters, and does not perform any operations;
The macro expression does not have any call overhead: (because the text replacement is directly performed, unlike functions that require parameters such as stacking, returning, etc.)
Recursive definitions cannot appear in macro expressions: (because the macro only performs one during the preprocessing period, and subsequent symbol compilers will not recognize it)
#define SUM(n) ((n>0) ? (SUM(n-1) + n) : 0)
int s = SUM(10); // 编译的时候就会报错,undefined reference SUM
3. Does the constant or expression defined by the macro have scope restrictions?
下面的程序合法么?
void def()
{
#define PI 3.1415926
#define AREA(r) r*r*PI
}
double area(double r)
{
retrun AREA(r);
}
int main()
{
double r = area(10);
return 0;
}
Analysis: There will be no errors in compiling and running. Explain that the macro has no scope restriction. As long as the definition is complete, the following code can be used. If used before the definition, an undefined reference error will be reported.
scope of 161c33d7c22d21 is only for variables and functions. The macro is expanded during the preprocessing period.
is no macro in 161c33d7c22d22 at the compile time, so there is no way to limit the scope of the macro.
4. Commonly used predefined macros
Macro | meaning | Example |
__FILE__ | File name to be compiled | file1.c |
__LINE__ | Current line number | 25 |
__DATE__ | Compile date | Jan 31 2012 |
__TIME__ | Compile time | 17:01:01 |
__STDC__ | Does the compiler follow the standard C specification | 1 |
This article is summarized from "C Language Advanced Course" by Tang Zuolin from "Ditai Software Academy".
If there are any errors or omissions, please correct me.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。