21天学会C++:Day6----内联函数

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

· CSDN的uu们,大家好。这里是C++入门的第六讲。
· 座右铭:前路坎坷,披荆斩棘,扶摇直上。
· 博客主页: @姬如祎
· 收录专栏:C++专题

21天学会C++:Day6----内联函数

目录

 1. 知识引入

2. 知识点讲解

2.1 内联函数的使用

2.2 内联函数的特性 

2.2 内联函数的注意点

3. 面试题


 1. 知识引入

在学C语言的宏时,我们了解了宏函数的概念与用法。我们也知道宏函数有一些易错点,稍不注意就可能出错!你若过不相信的话,就别看下面的代码自己写一个 a + b 的宏函数。

#define ADD(a, b) ((a) + (b))

int main()
{
	cout << ADD(10, 20) << endl;
	return 0;
}

不知道UU们写对了吗?为什么说宏函数容易写错呢?我们知道红的特性就是替换,这种特性会使我们遇到一些难以避免的错误,我们来看看这些常见的错误:

不加外面的括号替换之后由于运算符的优先级问题,导致结果出错!

#define ADD(a, b) (a) + (b)

int main()
{
	cout << ADD(10, 20) * 2 << endl; //使用宏函数
	cout << (10) + (20) * 2 << endl; //宏函数替换之后
	return 0;
}

 下面的代码同样也存由于运算符的优先级产生的问题:加法的优先级更高,导致结果出错。

#define ADD(a, b) (a + b)

int main()
{
	int a = 1, b = 2;
	cout << ADD(a | b, a & b) << endl; //使用宏函数
	cout << (a | b + a & b) << endl; //宏函数替换之后
	return 0;
}

那你可能会说了:那我每次都想正确的写法那样,多加几个括号不就能避免这种错误啦!很遗憾因为宏的替换特性,有些错误难以避免,观察如下代码:

我们尝试利用一个宏函数求解 b 的平方,但是我们用 ++b 来使用该函数,替换之后 ++b 会被执行两次,显然最终的结果并不是我们想要的。

#define Square(a) ((a) * (a))

int main()
{
	int b = 2;
	cout << Square(++b) << endl; //使用宏函数
	cout << ((++b) * (++b)) << endl; //宏函数替换之后
	return 0;
}

 但是呢宏还是有优点的,下面我们就来看看宏的优缺点:

优点:宏函数不需要建立函数栈帧,可以提高调用的效率。

缺点:不方便进行调试。(预处理阶段会进行宏的替换)

           代码可读性差,可维护性差,容易误用。

           没有类型安全的检查。(宏仅仅是替换嘛)。

C++ 是既想要宏的优点,又不想要宏的缺点。因此C++引入了内联函数。

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。

2. 知识点讲解

2.1 内联函数的使用

用法很简单,我们只要在一个函数返回值的前面加上 inline 关键字即可。像这样:

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


int main()
{
	cout << Add(2, 3) << endl;
	return 0;
}

2.2 内联函数的特性 

再来看看内联函数的概念吧:

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。

这里的在调用内联函数的地方展开,指的是:内联函数经过编译之后,会直接在调用处转化成汇编代码,而不是通过 call 指令,跳转到函数的实际地址处进行函数汇编代码的执行。 

在VS2019的debug模式下,默认是不会对程序进行优化的,我们看不到内联函数的展开,但是在release模式下又不支持调试,因此我们需要进行相关的设置才能看到内联函数的展开。

在项目---->属性中更改下面的设置即可 

21天学会C++:Day6----内联函数

我们通过调试下面的代码,然后查看汇编代码之后发现 Add 函数的调用并不是 call 函数地址而是直接在函数调用的地方展开,变成了汇编代码。

21天学会C++:Day6----内联函数

1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会
用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运
行效率。
2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建
议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不
是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性

2.2 内联函数的注意点

通过上面的调试过程我们直到内联函数是直接在调用处展开的,因此内联函数并没有函数地址。也就是说,内联函数不会出现在符号表中,也就意味着内联函数不可使用函数定义与函数声明分开的写法。

21天学会C++:Day6----内联函数

 为什么会报错呢?UU们不妨结合编译,链接的相关知识想一想。 

Add函数是内联函数,在调用Add函数的地方,编译器会在调用的地方展开。但是在调用Add函数的源文件中,只有Add函数的声明。 编译器无法做到在调用的地方展开,于是编译器会尝试通过 call 指令去调用函数,但是内联函数不会在符号表中出现,就会找不到函数的地址。因此会出现链接错误。

因此我们得出一个重要的结论:内联函数的声明与定义不可分离。

那应该怎么解决这个问题呢?很简单,直接在头文件里面写内联函数的定义即可。

21天学会C++:Day6----内联函数

3. 面试题

 宏的优缺点?
优点:
1.增强代码的复用性。
2.提高性能。
缺点:
1.不方便调试宏。(因为预编译阶段进行了替换)
2.导致代码可读性差,可维护性差,容易误用。
3.没有类型安全的检查 。
C++有哪些技术替代宏?
1. 常量定义 换用const enum
2. 短小函数定义 换用内联函数

 21天学会C++:Day6----内联函数文章来源地址https://www.toymoban.com/news/detail-470695.html

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

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

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

相关文章

  • 『C++成长记』C++入门——内联函数

     🔥 博客主页: 小王又困了 📚 系列专栏: C++ 🌟 人之为学,不日近则日退  ❤️ 感谢大家点赞👍收藏⭐评论✍️ 目录 一、内联函数 📒1.1内联函数的概念 📒1.2内联函数的特征 二、auto 📒2.1auto简介 📒2.2auto使用规则 📒2.3auto无法使用的场景 三、基于范围的for循

    2024年02月05日
    浏览(43)
  • 【C++入门】内联函数的秘密

    inline 修饰的函数叫内联函数,编译后会在调用内联函数的地方展开,没有调用函数的开销,可以提高程序运行的效率。 例子: 但是 inline 只是给编译器的一个建议,编译器自己会决定内联函数是否在调用处展开。 内联函数展开是一种空间换时间的做法,可能会造成代码膨胀

    2024年02月12日
    浏览(39)
  • C++从入门到精通——内联函数

    内联函数是一种优化手段,通过在编译时将函数调用替换为函数体本身的复制品,以减少函数调用的开销。它适用于函数体较小、调用频繁的情况。使用内联函数可以提高程序执行效率,但也会增加最终生成的代码大小。在C++中,可以使用 inline 声明内联函数。然而,

    2024年04月10日
    浏览(41)
  • 【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日
    浏览(38)
  • 【C++入门】你知道C++为什么会有内联函数吗?

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

    2024年02月03日
    浏览(76)
  • C++ DAY6

    又叫钻石继承,由公共子类派生出多个中间子类,又由多个中间子类派生出汇聚子类, 汇聚子类 会 从 中间子类 得到从 公共基类 继承下来的多个成员。 由于汇聚子类会得到中间子类从公共基类继承下来的多份基类成员,故引出了虚继承的概念 为了使汇聚子类只保存一份中

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

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

    2024年02月04日
    浏览(68)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包