C语言宏基础总结
2015-11-03 20:35
225 查看
最近在做一些项目的时候,不小心把NDK下面的一些宏写得有问题,导致一些编译不过的问题。所以,总结一下。
这些知识都可以在 GCC 文档上找到,本文主要参考博文《C语言宏的特殊用法和几个坑》
在预处理阶段:
(2)宏函数
宏名之后带括号的宏被认为是宏函数。用法和普通函数一样,只不过在预处理阶段,宏函数会被展开。优点是没有普通函数保存寄存器和参数传递的开销,展开后的代码有利于CPU cache的利用和指令预测,速度快。缺点是可执行代码体积大。
在宏体中,如果宏参数前加个#,那么在宏体扩展的时候,宏参数会被扩展成字符串的形式.如:
调用是使用
这种用法可以用在assert中,如果断言失败,可以将失败的语句输出到反馈信息中。
(2) 连接(Concatenation)
在宏体中,如果宏体所在标示符中有##,那么在宏体扩展的时候,宏参数会被直接替换到标示符中。如:
在宏扩展的时候
会被扩展成:
交叉引用,宏体也只会展开一次,foo只会展开成(4 + foo),而展开之后foo的含义就要根据上下文来确定了。
宏参数中若包含另外的宏,那么宏参数在被代入到宏体之前会做一次完全的展开,除非宏体中含有#或##
这些知识都可以在 GCC 文档上找到,本文主要参考博文《C语言宏的特殊用法和几个坑》
基础
(1) 标示符别名#define PI 3.14159
在预处理阶段:
pi = PI结果是
pi=3.14159;
(2)宏函数
宏名之后带括号的宏被认为是宏函数。用法和普通函数一样,只不过在预处理阶段,宏函数会被展开。优点是没有普通函数保存寄存器和参数传递的开销,展开后的代码有利于CPU cache的利用和指令预测,速度快。缺点是可执行代码体积大。
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
y = min(1, 2);会被扩展成
y = ((1) < (2) ? (1) : (2));
宏特殊用法
(1)字符串化(Stringification)在宏体中,如果宏参数前加个#,那么在宏体扩展的时候,宏参数会被扩展成字符串的形式.如:
#define WARN_IF(EXP) \ do { if (EXP) \ fprintf (stderr, "Warning: " #EXP "\n"); } \ while (0)
调用是使用
WARN_IF (x == 0);会被扩展成:
do { if (x == 0) fprintf (stderr, "Warning: " "x == 0" "\n"); } while (0);
这种用法可以用在assert中,如果断言失败,可以将失败的语句输出到反馈信息中。
(2) 连接(Concatenation)
在宏体中,如果宏体所在标示符中有##,那么在宏体扩展的时候,宏参数会被直接替换到标示符中。如:
#define COMMAND(NAME) { #NAME, NAME ## _command } struct command { char *name; void (*function) (void); };
在宏扩展的时候
struct command commands[] = { COMMAND (quit), COMMAND (help), ... };
会被扩展成:
struct command commands[] = { { "quit", quit_command }, { "help", help_command }, ... };
注意事项:
预处理器采取的策略是只展开一次, 如定义下面的宏:
#define foo (4 + foo)
交叉引用,宏体也只会展开一次,foo只会展开成(4 + foo),而展开之后foo的含义就要根据上下文来确定了。
宏参数中若包含另外的宏,那么宏参数在被代入到宏体之前会做一次完全的展开,除非宏体中含有#或##
相关文章推荐
- 爬爬爬之路:OC语言(七) NSDate , 协议和代理
- C++自定义命名空间
- C++primer第五版第二章学习笔记
- 数组、指针和字符串(二)------C++学习笔记
- C语言语法基础--黑马程序员
- c语言的隐式转换
- C++中四种强制类型转换的区别
- 常量传递1
- C++ Primer Chap3
- C语言——基本概念
- C语言数据类型范围
- C++笔试中常见的小程序
- C++静态库与动态库
- C++primer学习:模板编程(4)
- 记录c语言入门学习一
- C++primer学习:模板编程(3):效率与灵活
- 优先权调度算法
- C++ primer ——3.2.3节
- Effective C++(五)
- VC++ 迭代器 iterator, const_iterator, const iterator