如果想定义一个非常简单的常量值,你有两种选择:
static const int my_constant = 5;
// 或者
#define MY_CONSTANT 5
二者的不同之处在于,前者是一个真正的变量,而后者是一个复制粘贴的行内表达式。
宏:与变量不同,你可以在需要“常量表达式”的上下文中使用宏,例如数组长度或 switch 语句
变量:与宏不同,你可以获得指向变量的指针。
“常量表达式”实际上非常实用,因此常常被定义为宏。而变量则更适合更大或更复杂的值,如结构实例。
宏与内联函数宏可以有参数,并扩展为 C 代码。
相较于函数,宏的优势在于:
宏产生的代码相当于直接粘贴到周围的代码中,而不像函数需要一个调用指令。这样代码的运行速度更快,因为函数调用需要额外的开销;
宏不需要规定类型。例如,任何数字类型都可以执行 x y 运算。如果写成函数,就必须声明参数,并指定类型,比如类型大小、是否有符号,因此使用很有限。
缺点:
参数需要反复计算。假设我们有一个宏 MY_MACRO(x),如果定义中多次使用 x,那么表达式 x 将被反复计算,因为它只是简单地复制和粘贴。而相比之下,函数的参数表达式只需要计算一次,然后将结果传递给函数。
宏更容易出错,因为它们是源代码级别。尽可能多使用括号,将宏的整个定义和每个参数都放到括号内,这样表达式就不会不小心被合并。
// 不推荐这种写法:
#define MY_MACRO(x) x x
// 应该写成:
#define MY_MACRO(x) ((x) (x))
除非你需要多种泛型,否则可以直接定义静态内联函数(static inline function),这样就可以兼具二者的优点。内联表示,函数中的代码应该直接编译到使用的地方,而不是被调用。你可以将静态内联函数放在头文件中,就像宏一样。