# C++ 宏定义(define)和内联函数(inline)的区别
面试高频指数:★★★☆☆
宏定义(#define
)和内联函数(inline
)都是为了减少函数调用开销和提高代码运行效率而引入的机制,但是它们的实现方式和作用机制略有不同。
# define
在 C/C++ 中,#define
是预处理指令的一种。
一般用于定义宏(macro),主要有两种用途:
- 定义常量
- 创建宏函数
无论哪种都是用于在编译时替换文本,也就是 define 实际上只是做文本的替换,可以使用 gcc -E
选项查看宏替换后的结果。
本篇我们主要讲宏函数的场景,举例:
#define SQUARE_SUM(x, y) ((x) * (x) + (y) * (y))
写宏函数一定要注意:参数和函数体应当用括号包围,避免因运算优先级导致的错误。
# inline
内联函数的定义和普通函数类似,只需在函数声明前加上 inline
关键字即可。
但是编译器并不一定会将所有声明为内联函数的函数都进行内联,是否内联取决于编译器的实现和优化策略。
内联函数的优点是类型安全、可调试、可优化,但是也存在一些问题。
由于函数体会被复制多次,会占用更多的代码段空间,而且在某些情况下可能会导致代码膨胀。
我们再从以下角度对比下宏定义和内联函数:
# 差别
# 1. 语义
宏定义使用预处理器指令 #define
定义。
它在编译期间将宏展开,并替换宏定义中的代码。
预处理器只进行简单的文本替换,不涉及类型检查。
内联函数使用 inline
关键字定义,它是一个真正的函数。
编译器会尝试将内联函数的调用处用函数体进行替换,从而避免函数调用的开销。
# 2. 类型检查:
宏定义就是单纯的字符替换,不涉及类型检查,容易导致错误。
#define SQUARE(x) ((x) * (x))
int main() {
int a = 5;
double b = 5.5;
// 这里没有类型检查,但在运行时可能导致问题
double result = SQUARE(b);
}
内联函数会进行类型检查,更加安全。
inline int square(int x) {
return x * x;
}
int main() {
int a = 5;
double b = 5.5;
// 下面这行代码将导致编译错误,因为类型不匹配
double result = square(b);
}
# 3. 内联函数可以进行调试,宏定义的“函数”无法调试。
# 4. 宏可能导致不合理计算
在 inline 函数传递参数只计算一次,而在使用宏定义的情况下,每次在程序中使用宏时都会计算表达式参数,因此宏会对表达式参数计算多次。 因为宏只是做替换,可能会把同样的表达式替换到多个地方。
#define MAX(a, b) ((a) > (b) ? (a) : (c))
int x = 1;
int y = MAX(x++, 10);
// 宏定义 x++ 会被执行两次, 因为 x++ 会被替换到两个地方,使用内联函数则不会出现这个问题
最新原创的文章都先发布在公众号,欢迎关注哦~,
扫描下方二维码回复「CS」可以获得我汇总整理的计算机学习资料~