第21课 宏定义与使用分析

C语言中的宏定义:

 

定义宏常量:

 就宏定义来说,这是正确的,预处理器可以编译过。 但是就真正的编译来说,这是错误的,真正的编译会有语法错误。

示例程序:

 1 #define ERROR -1
 2 #define PATH1 "D:\test\test.c"
 3 #define PATH2 D:\test\test.c
 4 #define PATH3 D:\test\
 5 test.c
 6 
 7 int main()
 8 {
 9     int err = ERROR;
10     char* p1 = PATH1;
11     char* p2 = PATH2;
12     char* p3 = PATH3;
13 }

执行预处理,gcc -E test.c -o test.i,预处理器处理之后结果如下:

 

预处理器进行直接的文本替换,是不会进行语法检查的。第4行最后一个\会被认为是接续符,将第5行接到第4行。

再继续执行编译的话,16,17行会报错。

宏常量和const常量是不同的,const常量本质是变量,要占用内存空间,而define出来的宏是个字面量,不会占用内存空间。

宏定义表达式:

 

在C语言中,我们无法定义一个函数来求数组的大小,但是可以定义一个宏函数,来做这件事。

示例程序:

 1 // #include <stdio.h>
 2 
 3 #define _SUM_(a, b) (a) + (b)
 4 #define _MIN_(a, b) ((a) < (b) ? (a) : (b))
 5 #define _DIM_(a) sizeof(a)/sizeof(*a)
 6 
 7 
 8 int main()
 9 {
10     int a = 1;
11     int b = 2;
12     int c[4] = {0};
13 
14     int s1 = _SUM_(a, b);
15     int s2 = _SUM_(a, b) * _SUM_(a, b);
16     int m = _MIN_(a++, b);
17     int d = _DIM_(c);
18 
19     // printf("s1 = %d\n", s1);
20     // printf("s2 = %d\n", s2);
21     // printf("m = %d\n", m);
22     // printf("d = %d\n", d);
23 
24     return 0;
25 }

预处理结果如下:

打开printf打印行,运行结果如下:

 

程序的输出并不是我们的预期,可见宏代码块的副作用出来了。

第17行真正求得了数组的大小。

 

宏表达式与函数对比:

 

 宏定义的常量或表达式是否有作用域的限制?

 

示例程序:

 1 // #include <stdio.h>
 2 
 3 void def()
 4 {
 5     #define PI 3.1415926
 6     #define AREA(r) r * r * PI
 7 }
 8 
 9 double area(double r)
10 {
11     return AREA(r);
12 }
13 
14 int main()
15 {
16     double r = area(5);
17 
18     // printf("PI = %f\n", PI);
19     // printf("d = 5; a = %f\n", r);
20     
21     return 0;
22 }

编译结果如下:

 

预处理没有报错,这说明对于宏而言是没有作用域限制的。

作用域的概念是针对C语言里面的变量和函数的,它不针对宏,因为宏是被预处理器处理的。编译器不知道宏的存在。

强大的内置宏:

 

综合示例:

 1 #include <stdio.h>
 2 #include <malloc.h>
 3 
 4 #define MALLOC(type, x) (type*)malloc(sizeof(type)*x)
 5 
 6 #define FREE(p) (free(p), p=NULL)
 7 
 8 #define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__, __LINE__, s)
 9 
10 #define FOREACH(i, m) for(i=0; i<m; i++)
11 #define BEGIN {
12 #define END   }
13 
14 int main()
15 {
16     int x = 0;
17     int* p = MALLOC(int, 5);
18     
19     LOG("Begin to run main code...");
20     
21     FOREACH(x, 5)
22     BEGIN
23         p[x] = x;
24     END
25     
26     FOREACH(x, 5)
27     BEGIN
28         printf("%d\n", p[x]);
29     END
30     
31     FREE(p);
32     
33     LOG("End");
34     
35     return 0;
36 }

上述程序中定义的宏是无法用函数来取代的。

运行结果如下:

 

 

小结:

 

转载于:https://www.cnblogs.com/wanmeishenghuo/p/9536628.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值