【C++入门】内联函数

这篇具有很好参考价值的文章主要介绍了【C++入门】内联函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

个人主页:平行线也会相交
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创
收录于专栏【C++之路】
【C++入门】内联函数

什么是内联函数

内联函数概念:

内联函数就是以inline修饰的函数叫做内联函数,编译时会在调用内联函数的地方展开,没有函数调用占用建立栈帧的开销。

我们知道函数的调用是有消耗的,比如函数调用会建立栈帧(在栈上开辟一块空间)。
比如:

int Add(int x, int y)
{
	return (x + y) * 10;
}
int main()
{
	for (int i = 0; i < 10000; i++)
	{
		cout << Add(i, i + 1) << endl;
	}
	return 0;
}

上述代码中我们建立了10000个Add函数的栈帧,在C语言中可以使用宏函数来解决建立如此多的函数栈帧。C语言的解决方式是这样的,即:#define Add(x,y) ((x)+(y))一定要注意xy是一个表达式,所以C语言宏函数的这种解决方式其实是容易出错的,只要稍微不注意的话就会很容易出错而且宏函数不可以进行调试;同时宏函数的一个优势就是不需要建立栈帧,提高了调用效率。而对于C++而言,为了解决C语言的这种缺陷,C++提供的解决方案就是内联函数

内联函数的关键字是Inline

内敛函数使用起来也是非常的方便。就不如说上面代码中我们调用了10000次Add函数,下面请看内联函数使用样例:

inline int Add(int x, int y)
{
	return (x + y);
}

内联函数相对于C语言宏函数的解决方法而言就显得非常有优势:

1.不需要建立函数栈帧。
2.可读性强,且不易出错。
3.可以调试
4.使用起来简单。

然而并不是所有的函数都是可以使用内联函数的。内联函数只适用于短小的且频繁调用的函数。太长的函数如果使用内联函数的话会导致代码屏障

所以我们并不是要把所有的函数都弄成为内联函数,内联函数使用于短小而频繁调用的函数。如果函数比较长、又或者是递归函数不要让其称为内联函数。

内联函数特性

1.内联函数会在编译阶段用函数体替换函数调用。缺陷是可能会使可执行程序(或者目标文件)变大,优势就是减少了函数调用的开销,提高了运行效率。
2.内联函数只是编译器给我们的一个建议,最终函数是否会成为内联函数取决于编译器自己。如果我们把递归函数、比较长的函数加上inline的话就会被编译器否决掉。我们可以这样理解,内联函数只是我们向编译器发出的一个请求,然而编译器可以接收这个请求,当然也完全可以忽略这个请求。
3.内联函数不建议声明和定义分离,如果分离的话就会导致链接错误,因为inline被展开,此时就没有函数地址了,链接就会找不到。

现在有一个func函数,这个func函数经过编译后有50行指令,倘若在某个项目中总共需要调用10000次func函数。来看看是否使用内联函数的区别。

情况1:如果func函数不是内联函数:总共需要指令10000+50行,每次调用都是直接跳转到func函数去执行func函数(即call func(0x11223344)),每次跳转过去执行的是一样的,所以是+而不是*
情况2:那如果func函数是内联函数,要把这50行指令展开放到调用的地方,即需要10000*50行指令。这样就会导致可执行程序变大

我们以下面这段代码为例,看看如果加上inline会如果,如果不加inline又会如何。
在这之前我们首先要知道:

在Debug模式下,需要我们对编译器进行设置,否则内联函数不会展开,因为默认在Debug环境下不会对代码进行优化。

#include<iostream>
using namespace std;

inline int Add(int x, int y)
{
	return (x + y);
}
int main()
{
	for (int i = 0; i < 10000; i++)
	{
		cout << Add(i, i + 1) << endl;
	}
	return 0;
}

我们来看一下编译器是否会支持我们把Add函数弄为Inline

【C++入门】内联函数

我们发现这里出现call Add(07FF76C5E13CAh),发现Add函数并没有称为Inline。这就是因为默认Debug模式下内联不会起作用。所以我们要调一调属性:

【C++入门】内联函数

然后依然是在Debug模式下进行调试,请看:

【C++入门】内联函数
现在我们发现并没有出现call Add,因为Add函数展开了,此时Add函数就是内联函数
现在我们改一下Add函数的内容(但依然加上Inline)使得编译器认为Add函数不应该是内联函数,我们把Add函数改成这样,请看:

inline int Add(int x, int y)
{
	cout << "abca" << endl;
	cout << "abca" << endl;
	cout << "abca" << endl;
	cout << "abca" << endl;
	cout << "abca" << endl;
	cout << "abca" << endl;
	cout << "abca" << endl;
	return (x + y);
}

我们判断一下此时虽然我们在Add函数前加上了Inline,但此时编译器真的认为Add函数是内联函数吗?请看:

【C++入门】内联函数
我们可以看到这里并没有把Add函数进行展开,故Add函数此时并不是内联函数,编译器认为Add函数太长了,不应该把Add函数弄成内联函数,否则就可能出现代码屏障,进而导致最后的可执行程序(或者目标文件)变得非常大。就算我们在Add函数前加上Inline也依旧不会起作用。

我们来看看内联函数的特性3:内联函数不建议声明和定义分离,如果分离的话就会导致链接错误,因为inline被展开,此时就没有函数地址了,链接就会找不到。

这里举个例子:

//main().cpp
#include"func.h"
int main()
{
	func(100);
	return 0;
}


//func.cpp
#include"func.h"
void func(int i)
{
	cout << i << endl;
}

//func.h
#include<iostream>
using namespace std;
inline void func(int i);

运行结果如下:
【C++入门】内联函数
这里编译没有出现问题,而是链接出现了问题,即链接不上,为什么这里明明有func函数的定义却找不到呢?
程序在进行编译之后会进行链接,因为只有声明没有定义,但是声明的时候发现func函数是一个内联函数,那好,既然是内联函数那就展开就好了,但是问题又来了,我们想展开这个内联函数却又发现展不开,因为这里只有声明,于是编译器只能call函数func的地址,于是拿着修饰函数名?func@@YAXH@Z去符号里找发现又找不到,因为内联函数不会生成符号表,更不会有地址(内联函数认为在需要调用自己的时候直接展开了)。故在链接阶段就找不到函数func的定义。所以内联函数声明和定义不能进行分离,还是那句话:内联函数不会生成符号表,更不会有地址(因为内联函数认为自己会直接进行展开,根本不需要被call。所以链接的时候找不到函数func的定义,就直接报错了。

我们应该这样写内联函数(不要声明和定义分离):

//main().cpp
#include"func.h"
int main()
{
	func(100);
	test();
	return 0;
}


//func.cpp
#include"func.h"
void test()
{
	func(100);
}

//func.h
#include<iostream>
using namespace std;

//inline void func(int i);

inline void func(int i)
{
	cout << i << endl;
}
void test();

运行结果如下:
【C++入门】内联函数
好了,以上就是C++中的内联函数的介绍。
到这里啦,再见各位!!!

【C++入门】内联函数文章来源地址https://www.toymoban.com/news/detail-429235.html

到了这里,关于【C++入门】内联函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++入门】引用、内联函数、auto 关键字

    从语法上理解,引用就是给变量取一个 别名 ,它没有独立空间,和它引用的变量共用一块空间。 例子: 值得注意的是,C++ 中的引用一经初始化,后面是改变不了指向的(这点与Java有所不同),而且引用是必须初始化的。 引用的类型也必须和原变量对应,显然,你肯定不能

    2024年02月16日
    浏览(47)
  • 【c++速通】入门级攻略:什么是内联函数?函数重载又是什么?

    🎥 屿小夏 : 个人主页 🔥个人专栏 : C++入门到进阶 🌄 莫道桑榆晚,为霞尚满天! 在上一篇文章中我们了解到了命名空间和缺省函数的存在,以及C++为什么要引入它们。本章将继续C++在C语言上扩展出的语法,以帮助大家快速入门。函数竟然还有内联的形式?函数重载,重

    2024年02月06日
    浏览(39)
  • 【C++初阶】C++入门——内联函数、auto、范围for、nullptr

     普通的函数在调用的时候会开辟函数栈帧,会产生一定量的消耗,在C语言中可以用 宏函数 来解决这个问题,但是宏存在以下缺陷: 复杂、容易出错、可读性差、不能调试 。为此,C++中引入了 内联函数 这种方法。  以 inline 修饰 的函数叫做内联函数, 编译时 C++编译器会

    2024年02月16日
    浏览(44)
  • C++入门:内联函数,auto,范围for循环,nullptr

    目录 1.内联函数 1.1 概念 1.2 特性  1.3 内联函数与宏的区别 2.auto(C++11) 2.1 auto简介 2.2 auto的使用细则 2.3 auto不能推导的场景 3.基于范围的for循环(C++11) 3.1 范围for的语法 3.2 范围for的使用方法 4.指针空值nullptr(C++11) 4.1 C++98中的指针空值 以inline修饰的函数叫做内联函数,编

    2024年02月11日
    浏览(37)
  • 【C++入门】你知道C++为什么会有内联函数吗?

    👦个人主页:@Weraphael ✍🏻作者简介:目前学习C++和算法 ✈️专栏:C++航路 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨ 本章是补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的。 我

    2024年02月03日
    浏览(76)
  • 【C++初阶】二、入门知识讲解(引用、内联函数、auto关键字、基于范围的for循环、指针空值nullptr)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【C++初阶】一、入门知识讲解 (C++、命名空间、C++输入输出、缺省参数、函数重载)-

    2024年02月04日
    浏览(68)
  • 从C语言到C++(第一章_C++入门_下篇)内联函数+auto关键字(C++11)+范围for +nullptr

    目录 1. 内联函数 1.1 内联函数的概念 1.2 内联函数的特性 1.3 宏的优缺点和替代方法 2. auto(C++11) 2.1 改版前的auto 2.2 C++11的auto 2.3 auto 的使用场景 2.4 使用auto的注意事项 3. 范围 for(C++11) 3.1 范围 for 的用法 3.2 范围 for 的使用条件 4. 指针空值 nullptr 4.1 C++ 98 中的指针空

    2023年04月21日
    浏览(47)
  • 【C++】函数重载 & 引用 & 内联函数

    目录 一,函数重载 1,函数重载的概念 2,C++支持函数重载的原理 二,引用 1,引用概念 2,引用特性 3,常引用 4,做参数 5,做返回值 6,传值、传引用效率比较 7,值和引用的作为返回值类型的性能比较 8,引用和指针的区别 三,内联函数 1,概念 2,特性 自然语言中,一个

    2024年02月08日
    浏览(41)
  • 【C++初阶】:内联函数

    在c语言中,如果一个函数较短并且会被重复使用,那么我们就可以把该函数换成一个宏函数。 贴个小知识,宏函数有许多的坑也是面试官喜欢考的点,如果对行函数不太了解可以看看这篇关于宏的部分传送门 宏函数的优点:不会建立栈帧,提高使用效率。 宏函数的缺点:复

    2023年04月25日
    浏览(33)
  • C++内联函数详解

    目录 如何定义内联函数? 内联函数的优势 内联函数的缺点 内联函数的使用场景 示例代码 总结 在C++中,内联函数是一种特殊的函数,它的作用是在程序编译时将函数的代码直接嵌入到调用该函数的代码中,从而避免了函数调用的开销。这种方式可以提高程序的执行效率,适

    2023年04月20日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包