【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推导的是同一类型,不能推导不同类型

相关文章
|
3月前
|
存储 安全 编译器
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(一)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值
|
3月前
|
存储 编译器 程序员
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(二)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值
|
3月前
|
程序员 C++ 开发者
C++入门教程:掌握函数重载、引用与内联函数的概念
通过上述介绍和实例,我们可以看到,函数重载提供了多态性;引用提高了函数调用的效率和便捷性;内联函数则在保证代码清晰的同时,提高了程序的运行效率。掌握这些概念,对于初学者来说是非常重要的,它们是提升C++编程技能的基石。
30 0
|
2月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
61 2
|
2月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
113 5
|
2月前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
112 4
|
2月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
152 4
|
3月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
35 4
|
3月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
33 4
|
3月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
33 1