内联函数
1.内联函数的概念
对于调用次数很多,而且函数体很小的函数,每次调用函数的时候,都会开辟函数栈帧,这样会使效率降低,在C语言中,对于这种情况我们就会定义宏函数用于解决这个问题。但是,宏函数也会有很多缺陷:
宏函数的缺陷
- 不能调试
- 没有类型检查
- 导致代码可读性差,可维护性差,容易误用
所以,在C++中,提出了inline(内联函数)的概念。
什么叫内联函数
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。
不用inline修饰
用inline修饰
可以看到没有使用inline修饰时汇编代码中有call这个指令,使用inline修饰的小函数,汇编指令中就没有call这个指令,而且不会开辟函数栈帧,没有压栈这个操作。
注:这里如果读者自己去试验会发现使用inline修饰也会看到有call这个指令存在,这是为什么呢?
- 在release模式下,查看编译器生成的汇编代码中是否存在call Add
- 在debug模式下,需要对编译器进行设置,否则不会展开(因为debug模式下,编译器默认不会对代码进行优化,以下给出vs2013的设置方式)
2.内联函数的特性
1、inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。
2、inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。下图为
- 《C++prime》第五版关于inline的建议:
3、inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,所以在写入符号表这个操作的过程中,inline修饰的函数时不会写入符号表的,就没有函数地址了,链接就会找不到。
auto关键字(C++11)
1.auto简介
在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但遗憾的是一直没有人去使用它,所以在C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
例如:
我们可以看出编译器自动推导出了变量b和变量c的的类型分别为int和char。
2.auto使用细则
2.1.auto和指针,引用结合
用auto声明指针类型的时候,使用auto和auto*都可以,但是使用auto声明引用类型的时候必须使用auto&,
2.2.在同一行定义多个变量
在同一行定义多个变量的时候,这些变量必须是相同类型的,因为编译器只会对第一个类型进行推导,然后用这个类型去定义其他变量。
可以看到,上述代码会报错,同一行代码中auto推导的是同一类型,不能推导不同类型。