c语言已经完结,有兴趣的可以收藏一下我的c语言专栏,感谢各位大佬支持!
1.宏是什么?
#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义
宏(define macro)。
语法:
#define name( parament-list ) stuff
parament-list:是一个由逗号隔开的符号表。
2.宏的用法
#define SUM(x,y) ((x)+(y)) int main() { int a = 10; int b = 20; int ret = SUM(a, b); printf("%d\n", ret); return 0; }
简要说明:1宏已经被替换
3. 宏的注意事项
定义什么替换什么
来看这一例:
#define NUM(x,y) x+y int main() { int a = 2; int b = 3; printf("%d\n", NUM(a, b) * NUM(a, b)); //结果:11 return 0; }
原因:num(a,b)*num(a,b) = a + b * a + b=11
4. 宏和函数的区别
属性 | #define定义宏 | 函数 |
代码长度 | 如果多次调用,多次替换,如果是大长度宏其长度很长 | 函数只实现一次可以多次使用,如果多次调用,长度只有一份 |
执行速度 | 更快 | 函数调用和开辟都会有额外开销 |
操作符优先级 | 必须每个参数加上括号,否则操作符优先级可能会产生不可预料的后果 | 函数参数只在函数调用的时候求值一次,它的结果值传递给函数。表达式的求值结果更容易预测 |
带有副作用参数 | 多次调用宏会有不可预料的后果 | 函数参数只在传参的时候求值一次,结果更容易控制,只需关注是传值还是传址 |
参数类型 | 宏的参数和类型无关,可以使用与任何参数类型 | 函数参数与类型有关,类型取决于使用目的,传值,传址,还是拿一个字节数据char* |
调试 | 不方便调试,编译期间就已经替换 | 可调试 |
递归 | 不可递归 | 可递归 |
宏带副作用参数:
#define MAX(a, b) ( (a) > (b) ? (a) : (b) ) int main() { int x = 5; int y = 8; int z = MAX(x++, y++); printf("x=%d y=%d z=%d\n", x, y, z);//输出的结果是什么 return 0; } //( (x++) > (y++) ? (x++):(y++) ) //输出结果:x=6,y=10,z=9
5.命名要求
- 宏名必须大写
- 函数不要全部大写
6. 条件编译
6.1 常见条件编译指令及应用场景
1.单分支
- 编译指令:
#if 常量表达式
//…
#endif
应用场景:
int main() { #if 4>2 printf("hello world!\n"); #endif return 0; } //输出hello world
2.多分支
- 编译指令:
#if 常量表达式
//…
#elif 常量表达式
//…
#else
//…
#endif
应用场景:
int main() { #if 1>2 printf("xixi\n"); #elif 4>3 printf("haha\n"); #else printf("heihei\n"); #endif return 0; } //输出结果:haha
可不能和if else选择语句混淆,多分支条件编译从上往下走,如果有一个分支成立,后面分支就不再执行;但是选择语句是从上往下走,有一个分支成立,继续查看后面分支是否成立
3.判断是否被定义
编译指令
#if 常量表达式
#ifdef symbol
//操作
#endif
#elif 常量表达式
#ifdef symbol
//操作
#endif
#endif
条件编译指令也支持嵌套,注意#endif结束本次嵌套
5.删除宏定义
- 编译指令:
#undef
#define DEF int main() { #undef DEF//删除DEF宏定义了 #ifdef DEF printf("hehe\n"); #endif return 0; }
- 分位三个阶段:预编译、编译、汇编 ↩︎