c++总复习
一、C++ 内联函数的定义及作用
1. 定义
在 C++ 中,内联函数是一种特殊的函数,它在编译阶段会被编译器尝试直接嵌入到调用它的地方,而不是像普通函数那样进行常规的函数调用(即通过函数栈来传递参数、保存返回地址等一系列操作)。
例如,下面是一个简单的内联函数示例:
#include <iostream>
// 定义内联函数
inline int add(int a, int b) {
return a + b;
}
int main() {
int num1 = 5;
int num2 = 3;
// 调用内联函数
int result = add(num1, num2);
std::cout << "两数之和为: " << result << std::endl;
return 0;
}
在上述代码中,add
函数被定义为内联函数,编译器在处理main
函数中对add
函数的调用时,会尝试将add
函数的代码直接嵌入到调用点处,就好像把return a + b;
这行代码直接放在了int result = add(num1, num2);
的位置一样(实际情况可能会因编译器优化策略有所不同)。
2. 作用
- 提高程序执行效率:对于一些简单的、频繁被调用的函数,使用内联函数可以减少函数调用的开销。普通函数调用时涉及到创建函数栈帧、传递参数、保存返回地址等操作,这些操作会消耗一定的时间和空间。而内联函数直接将函数体嵌入到调用处,避免了这些额外的开销,从而有可能提高程序的执行速度,特别是在函数体代码较短且被频繁调用的情况下,效率提升较为明显。
- 增强代码可读性:内联函数可以让代码在逻辑上更加清晰。它允许将一段具有特定功能的代码封装成一个类似函数的形式,在需要使用该功能的地方直接调用,就像调用普通函数一样方便,同时又能在一定程度上避免函数调用带来的性能损耗,使得代码既易于理解又具有较好的性能。
二、内联函数与普通函数的区别
1. 函数调用方式
- 普通函数:当调用普通函数时,程序会在运行时跳转到函数所在的内存地址,创建函数栈帧,将参数压入栈中,执行函数体中的代码,然后将返回值返回给调用点,并销毁函数栈帧。这个过程涉及到较多的系统开销,特别是对于频繁调用的小函数,这些开销可能会对程序性能产生一定影响。
- 内联函数:编译器在编译阶段会尝试将内联函数的代码直接嵌入到调用它的地方,从调用者的角度看,就好像内联函数的代码是直接写在调用点处一样,不存在函数调用的那种跳转和栈帧创建与销毁的过程(除非编译器无法将其内联,此时会按照普通函数调用处理)。
2. 代码展开方式
- 普通函数:无论在多少个地方调用普通函数,函数的代码始终只存在一份,位于内存中的特定函数区域。每次调用都是通过跳转指令找到该函数并执行。
- 内联函数:内联函数的代码会在每个调用它的地方展开(如果编译器决定内联它)。也就是说,如果一个内联函数在程序的多个地方被调用,那么它的代码会在每个调用点处都出现一份,这可能会导致代码体积增大,但在某些情况下能换来执行效率的提升。
3. 编译处理方式
- 普通函数:编译器会对普通函数进行常规的编译处理,包括语法检查、生成目标代码等,并且会为其生成独立的函数符号表项,以便在程序运行时能够正确地找到并调用该函数。
- 内联函数:编译器会在编译阶段对内联函数进行特殊处理,除了进行常规的语法检查等操作外,还会根据内联函数的定义以及调用情况,决定是否将其代码真正嵌入到调用点处。如果编译器认为内联函数不适合内联(例如函数体过于复杂、包含递归等情况),那么它会将内联函数当作普通函数来处理,同样会生成独立的函数符号表项。
三、内联函数的定义和使用
1. 定义内联函数
可以使用inline
关键字来定义内联函数,一般有以下两种常见的定义方式:
方式一:在函数声明处使用inline
关键字
// 函数声明并指定为内联函数
inline int multiply(int x, int y);
// 函数定义
int multiply(int x, int y) {
return x * y;
}
在这种方式中,先在函数声明前加上inline
关键字声明该函数为内联函数,然后在后续的函数定义中给出函数体的具体实现。
方式二:直接在函数定义处使用inline
关键字
// 直接定义内联函数
inline int divide(int a, int b) {
if (b == 0) {
throw std::runtime_error("除数不能为零");
}
return a / b;
}
这种方式是直接在函数定义的开头加上inline
关键字,将函数定义为内联函数,这样就不需要单独的函数声明步骤了(当然,也可以先声明再定义,只要在定义时也带有inline
关键字即可)。
2. 使用内联函数
使用内联函数的方式与使用普通函数基本相同,就是在需要执行该函数所提供的功能的地方,按照函数的调用语法进行调用即可。例如:
int main() {
int num1 = 10;
int num2 = 2;
// 调用内联函数multiply
int product = multiply(num1, num2);
// 调用内联函数divide
int quotient = divide(num1, num2);
std::cout << "两数之积为: " << product << std::endl;
std::cout << "两数之商为: " << quotient << std::endl;
return 0;
}
在上述main
函数中,分别调用了前面定义的内联函数multiply
和divide
,就像调用普通函数一样,传入相应的参数,然后获取函数的返回值并进行后续的处理。
需要注意的是,虽然使用inline
关键字定义了函数,但最终是否能真正实现内联,还是由编译器根据函数的具体情况(如函数体的复杂程度、调用频率等)来决定。有些情况下,即使定义为内联函数,编译器可能也不会将其代码嵌入到调用点处,而是按照普通函数来处理。
原文地址:https://blog.csdn.net/raojiaxv/article/details/143921112
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!