【C++】初识C++2(内联函数&auto关键字&范围for循环&nullptr)(上)

简介: 【C++】初识C++2(内联函数&auto关键字&范围for循环&nullptr)(上)

内联函数


1.内联函数的概念

对于调用次数很多,而且函数体很小的函数,每次调用函数的时候,都会开辟函数栈帧,这样会使效率降低,在C语言中,对于这种情况我们就会定义宏函数用于解决这个问题。但是,宏函数也会有很多缺陷:


宏函数的缺陷

  1. 不能调试
  2. 没有类型检查
  3. 导致代码可读性差,可维护性差,容易误用

所以,在C++中,提出了inline(内联函数)的概念。


什么叫内联函数

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

4864d6cd54deb51a25610b2a66646f82.png

不用inline修饰

8dec66fca341c6af5cc2f8b30d7ed088.png

用inline修饰

可以看到没有使用inline修饰时汇编代码中有call这个指令,使用inline修饰的小函数,汇编指令中就没有call这个指令,而且不会开辟函数栈帧,没有压栈这个操作。


注:这里如果读者自己去试验会发现使用inline修饰也会看到有call这个指令存在,这是为什么呢?


  1. 在release模式下,查看编译器生成的汇编代码中是否存在call Add
  2. 在debug模式下,需要对编译器进行设置,否则不会展开(因为debug模式下,编译器默认不会对代码进行优化,以下给出vs2013的设置方式)

182600a121edb82757da4a94012d5df2.png


2.内联函数的特性


1、inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。


2、inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。下图为

  1. 《C++prime》第五版关于inline的建议:

205ac2153ac124daaaf7bda765660b5c.png

3、inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,所以在写入符号表这个操作的过程中,inline修饰的函数时不会写入符号表的,就没有函数地址了,链接就会找不到。


auto关键字(C++11)


1.auto简介

在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但遗憾的是一直没有人去使用它,所以在C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

例如:

264ccac8e10c265683a214357865800c.png

我们可以看出编译器自动推导出了变量b和变量c的的类型分别为int和char。


2.auto使用细则


2.1.auto和指针,引用结合

用auto声明指针类型的时候,使用auto和auto*都可以,但是使用auto声明引用类型的时候必须使用auto&,

7329387a791de0eeaadaef89ee35faa7.png

2.2.在同一行定义多个变量

在同一行定义多个变量的时候,这些变量必须是相同类型的,因为编译器只会对第一个类型进行推导,然后用这个类型去定义其他变量。

2ce14cde33dd86b987624e3e624b6885.png

可以看到,上述代码会报错,同一行代码中auto推导的是同一类型,不能推导不同类型

相关文章
|
1月前
|
算法 安全 编译器
【C++ 关键字 override】C++ 重写关键字override(强制编译器检查该函数是否覆盖已存在的虚函数)
【C++ 关键字 override】C++ 重写关键字override(强制编译器检查该函数是否覆盖已存在的虚函数)
27 0
|
18天前
|
编译器 C语言 C++
【C++】C++入门第一课(c++关键字 | 命名空间 | c++输入输出 | 缺省参数)
【C++】C++入门第一课(c++关键字 | 命名空间 | c++输入输出 | 缺省参数)
|
19天前
|
存储 程序员 编译器
C++注释、变量、常量、关键字、标识符、输入输出
C++注释、变量、常量、关键字、标识符、输入输出
|
20天前
|
编译器 C语言 C++
【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例
【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例
|
24天前
|
C++
C++ While 和 For 循环:流程控制全解析
本文介绍了C++中的`switch`语句和循环结构。`switch`语句根据表达式的值执行匹配的代码块,可以使用`break`终止执行并跳出`switch`。`default`关键字用于处理没有匹配`case`的情况。接着,文章讲述了三种类型的循环:`while`循环在条件满足时执行代码,`do/while`至少执行一次代码再检查条件,`for`循环适用于已知循环次数的情况。`for`循环包含初始化、条件和递增三个部分。此外,还提到了嵌套循环和C++11引入的`foreach`循环,用于遍历数组元素。最后,鼓励读者关注微信公众号`Let us Coding`获取更多内容。
21 0
|
1月前
|
安全 算法 程序员
【C++ 空指针的判断】深入理解 C++11 中的 nullptr 和 nullptr_t
【C++ 空指针的判断】深入理解 C++11 中的 nullptr 和 nullptr_t
49 0
|
1月前
|
存储 算法 编译器
【C++ 关键字 static_assert 相关问题】C++ 关于静态断言的编译问题 ,深入了解静态断言
【C++ 关键字 static_assert 相关问题】C++ 关于静态断言的编译问题 ,深入了解静态断言
29 0
|
1月前
|
安全 算法 程序员
【C++智能指针 空指针判断】深入探索C++智能指针:nullptr与empty的微妙差异
【C++智能指针 空指针判断】深入探索C++智能指针:nullptr与empty的微妙差异
29 1
|
1月前
|
算法 编译器 C++
【C++ 关键字的混合使用 】C++深度探索:auto、static、constexpr的交互影响与应用
【C++ 关键字的混合使用 】C++深度探索:auto、static、constexpr的交互影响与应用
31 0
|
5天前
|
存储 编译器 C语言
c++的学习之路:5、类和对象(1)
c++的学习之路:5、类和对象(1)
19 0