C++内联函数详解
C++内联函数详解
1.函数调用原理
"编译过程的最终产品是可执行程序--由一组机器语言指令组成。运行程序时,操作系统将这些指令载入计算机内存中,因此每条指令都有特定的内存地址。计算机随后将逐步执行这些指令。有时(如有循环和分支语句时),将跳过一些指令,向前或向后跳到特定地址。常规函数调用也使程序跳到另一个地址(函数的地址),并在函数结束时返回。下面更详细地介绍这一过程的典型实现。执行到函数调用指令时,程序将在函数调用后立即存储该指令的内存地址,并将函数参数复制到堆栈(为此保留的内存块),跳到标记函数起点的内存单元,执行函数代码(也许还需将返回值放入寄存器中),然后跳回到地址被保存的指令处(这与阅读文章时停下来看脚注,并在阅读完脚注后返回到以前阅读的地方类似)。来回跳跃并记录跳跃位置意味着以前使用函数时,需要一定的开销。"
2.内联函数
内联函数提供了另一种选择。编译器将使用相应的函数代码替换函数调用。因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存。
3.内联函数的使用
在函数声明前加上关键字inline;
在函数定义前加上关键字inline。
示例如下:
#include<iostream> inline double square(double x){return x*x;} int main() { using namespace std; double a,b; double c = 13.0; a = square(5.0); b = square(4.5+7.5); cout<<"a="<<a<<",b="<<b<<endl; cout<<"c="<<c<<endl; cout<<"c squared="<<square(c++)<<endl; cout<<"now c="<<c<<endl; return 0; }
程序输出结果如下:
a=25,b=144
c=13
c square=169
now c=14
4.内联函数与宏定义的区别
C语言使用预处理器语句#define来提供宏。如下例所示:
#define SQUARE(X) X*X
宏定义时通过文本替换开实现的--X是参数的符号标记。
a = square(5.0);->a=5.0*5.0;
b = square(4.5+7.5);->b=4.5+7.5*4.5+7.5
d = square(c++);->d=c++*c++
可以看出,对于b,需要使用括号才能正常运算。
#define SQUARE(X) ((X)*(X))
对于c,却仍递增了两次。
因此,宏定义和内联函数存在本质的区别,转换的时候应考虑是否转换后功能是否正常。
5.什么时候使用内联函数
如果执行函数代码的时间比处理函数调用机制的时间长,则节省的时间占比很小。若代码执行时间很短,则内联函数就可以节省函数调用的时间。
参考资料:《C++ Primer.Plus》 pp.253-255
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
java基本数据类型
Java基本数据类型 变量就是申请内存来存储值,也就是说,当创建变量的时候,需要在内存中申请空间。 内存管理系统根据变量类型为变量分配空间,分配空间只能用来存贮该类型数据 因此,通过定义不同类型变量,可以在内存中存储整数,小数或者字符。 Java的两大数据类型; 内置数据类型 应用数据类型 内置数据类型 Java语言提供了八种基本类型,六种字符类型(四个整数类型,两个浮点型),一个字符类型,还有一种布尔型。 byte: byte数据类型是8位,有符号的,以二进制补码表示的整数。 最小值是-128(-2^7); 最大值127(2^7-1); 默认值是0 byte类型用在大型数组中节约空间,主要代替整数,因为byte变量占用的空间只有int类型的四分之一; 例子;byt a =100,byte b = -50 short类型是16位,有符号的以二进制补码表示的整数 int类型是32位,有符号的以二进制补码表示的整数 long数据类型是64位,有符号的以二进制补码表示的整数。 float数据类型是单精度,32位,符号IEEE 754标准的浮点数。 double数据类型是双精度,64位,符合I...
- 下一篇
Maven的使用和学习初体验
Maven初体验 因为三年的学习中,随着自己学习Java的深入,也越来越理不清自己的应用的依赖关系。比如起初 因为一个StringUtil而导入的Apache的commens扩展包。 还有玩数据库时导入的MySQL驱动包随后还有oracle的驱动包 然后玩JavaWeb从Tomcat中拿了个servlet的包 然后是我学习最漫长的一段时间中,从spring,springMVC,mybatis,随后的hibernate,Struts2,无数的包就不列出了。 随后又玩大数据和云计算,玩起了hadoop,hdfs,yarn,MapReduce,导入的包很多很复杂,不过幸好eclipse的插件帮我完成了这个导入的过程。 玩大数据的过程中做反向索引又去引入的分词包analyze。 随后的项目过程中用到将数据导出到外部excel中,用到了Apache的POI。 ... 随着学习的深入,每次构建一个项目都需要去思考依赖关系,而且往往会在做项目的过程中或者调试的过程中因为导入的包不足而报错。 其实之前早就浅浅接触过maven和GitHub,但是因为当时自己的项目规模完全还没到需要系统管理的程度,所...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7安装Docker,走上虚拟化容器引擎之路