C语言宏定义详解
来源:互联网 发布:鼠标 淘宝店推荐 编辑:程序博客网 时间:2024/05/18 10:13
宏定义
0.前言
- 本文章的程序是在linux下测试通过的
本文的分析通过了下面的命令来查看预编译结果
gcc -E filename.c -o filename.i
这条命令的作用是生成预处理文件filename.i
gcc -S filename.c -o filename.s
这条命令的作用是生成预编译文件filename.s
gcc -c filename.c -o filename.o
这条命令的作用是生成汇编文件filename.s
1.宏定义的特点
1.#define表达式给有函数调用的假象,却不是函数2.#define表达式可以比函数更强大3.#define表达式比函数更容易出错
2.宏定义函数
#define SWAP(a, b) \{ \ int temp = a; \ a = b; \ b = temp; \}
上面的语句会对变量直接进行覆盖
函数不是真正意义上的交换,只是复制了一份
3.宏定义表达式
- 与函数的对比
1.在于编译器被处理,编译器不知道宏表达式的存在
2.用“实参”完全替代形参,不进行任何计算
3.没有任何“调用”的开销
4.不能出现递归定义
#define SUM(a, b) (a)+(b)#define MIN(a, b) ((a < b) ? a : b)int main(){ int a = 2, b = 5; SWAP(a, b); printf("%d %d\n", a, b); printf("%d\n", SUM(a, b)); //是期望的值 printf("%d\n", MIN(a, b)); //是期望的值 printf("%d\n", SUM(a, b) * SUM(a, b)); //不是期望的值 printf("%d\n", MIN(a++, b)); //不是期望的值 return 0;}
问题:
为什么上面的例子中最后的printf没有出现预想的值
解决:
编译器只是对宏定义进行了替换,替换后的结果如下:
#define SUM(a, b) (a)+(b)#define MIN(a, b) ((a < b) ? (a) : (b))int main(){ int a = 2, b = 5; SWAP(a, b); printf("%d %d\n", a, b); printf("%d\n", (2)+(5)); //是期望的值 printf("%d\n", ((2<5) ? (2) : (5))); //是期望的值 printf("%d\n", (2)+(5) * (2)+(5)); //不是期望的值 printf("%d\n", ((2++<5) ? (2++) : (5))); //不是期望的值 return 0;}
看了上面的预编译的程序后恍然大悟
注意:
避免在宏里面写表达式,而应该写计算数组的大小,因为函数无法做到
4.系统宏定义和范围
1.系统的宏
1.__FILE__ 被编译的文件名2.__LINE__ 当前行号3.__DATE__ 编译时的日期4.__TIME__ 编译时的时间5.__STDC__ 编译是否遵循标准c规范
2.作用:
1.可以通过宏来使用上面的系统的宏定义日志追踪2.如果使用函数会出现行号不匹配
3.扩展:
可以使用循环语句(do{}while(0))定义宏,do里面使用接续符链接语句,把多行语句接到一行里面
//#define LOG(s) printf("%s:%d %s\n", __FILE__, __LINE__, s);/*需要调用time.hlocaltime:将时间转化为本地时间asctime:将时间转换为正常(原本为毫秒)*/#define LOG(s) do{ \ time_t t; \ struct tm* ti; \ time(&t); \ ti = localtime(&t); \ printf("%s[%s:%d] %s\n", asctime(ti), __FILE__, __LINE__, s); \}while(0)/*int f1(int a, int b){ //#define 没有作用域的限制,需要#undef来结束,限制作用域 #define _MIN_(a, b) ((a) < (b) ? a : b) return _MIN_(a, b); #undef}int f2(int a, int b, int c){ return _MIN_(_MIN_(a, b), c);}*/void f(){ LOG("Enter f()...\n"); LOG("Exit f()...\n");}int main(){ LOG("Enter main...\n"); f(); LOG("Exit main...\n"); return 0;}
5.注意:
- 宏定义对空格比较敏感
#define f (x) ((x)-1)
- 说明:上式宏定义了个
f
,他的需要被替换为x
,但是后面又有个((x)-1)
没有任何定义,所以会报错。
1 0
- C语言宏定义详解
- C语言宏定义详解
- C语言宏定义详解
- C语言宏定义详解
- c语言宏定义详解
- C语言宏定义详解
- c语言宏定义详解
- C语言宏定义详解
- C语言宏定义详解 - [C,C++]
- C 详解C语言中的宏定义
- 详解C语言中的宏定义
- C语言中宏定义使用方法详解
- 详解C语言中的宏定义
- C/C++语言宏定义使用详解
- C语言的宏定义详解
- (转)C语言宏定义详解 - [C,C++]
- c语言宏定义
- C语言宏定义
- 我的推免经历
- GBDT和Xgboost模型对比总结
- 10.1 分别通过函数和重载运算符来实现复数相加
- PTA.5-1 复数相加
- 在每行、每列递增的二维数组中找出给定的target 的位置
- C语言宏定义详解
- c++ static_cast,const_cast,reinterpret_cast,dynamic_cast
- 树莓派使用uart串口与串口设备通信
- mysql开启slow_query_log
- win10下安装vmware tools,实现文件传送
- chrome插件
- 页面背景固定
- Sweet Alert Dialog:清新文艺,快意灵动的甜心弹框
- DOM模型演示---增删改查中的查询2