目录
内联函数
auto 关键字
范围for
指针空值nullptr
内联函数
以inline修饰的函数叫内联函数,编译时C++编译器会在调用函数的地方展开,没有函数调用建立栈帧的开销,可提升程序的运行效率。
例子:
#include <iostream>
using namespace std;
// 内联函数
inline int Add(int x, int y)
{
return x + y;
}
int main()
{
int ret = 0;
ret = Add(1,2);
cout << ret;
return 0;
}
而上面的程序在运行的时候并不存在调用函数名为Add()的栈帧,编译器的编译的时候将其展开了(release模式下) 。
inline支持声明和定义分离,但是不建议inline函数采用声明和定义分离的写法,因为当inline函数被展开后,是没有函数地址的,容易发生错误
注意:
inline 的作用有点类似C语言中的#define(宏), 但其比#define(宏) 更优秀,inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同。为何说是一个建议?假如用inline修饰递归函数,或者修饰频繁调用的函数,或者修饰多行代码的函数,编译器会自动忽略inline这个特性。
在《Effective C++ Second Edition》的条款1中,建议尽量用inline而不是用#define:
auto 关键字
在早期c/c++中auto的含义是,使用auto修饰的变量,是具有自动存储器的局部变量,但使用热度并不高,在C++11中,C++标准委员会赋予了auto全新的含义:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的便必须由编译器在编译时推导而得。
简而言之就是,auto可以自动推导变量的类型。在后续学习C++的过程中,随着程序越来越复杂,程序中用到的类型也会越来越复杂,例如 "std::vector<int>::const_iterator it = v1.begin()"等等语句。
例子:
#include <iostream>
using namespace std;
int main()
{
int a = 0;
// 10 是int类型,因此此处的auto在编译的时候自动推导为int
auto b = 10;
// &a 是指向int变量的指针类型,因此此处的auto在编译的时候自动推导为int*
auto ptr = &a;
// 若是想引用某个变量实体的话,需要在"加上&"
auto& c = a;
return 0;
}
注意:
auto不能作为函数的参数(C++20之前)。
auto崩直接用来声明数组。
为了避免于C++98中的auto发生混淆,C++11中只保留了auto作为类型指示符的用法。
范围for
在C++11中,C++引入了基于范围的for循环。可以使用范围for来遍历数组、string、vector、list等等,for循环后的括号用冒号 " : " 分为两部分:第一部分是范围内用于迭代的变量,第二部分则是表示被迭代的范围。
例子:
#include <iostream>
using namespace std;
int main()
{
int a[] = {1,2,3,4,5,6,7,8,9};
//for (int e : a)
for (auto e : a)
{
cout << e << " ";
}
cout << endl;
return 0;
}
指针空值nullptr
在C语言中,如果要给一个指针赋予空值,采用的做法是将其赋值为NULL,例如 " int* ptr = NULL;"。
实际上,NULL是一个宏,在C语言的头文件(stddef.h)中可以找到" #define NULL 0",NULL可能会被定义为字面常量0,或者被定义为无类型指针的常量,但是这种行为在某些程序下会存在一些问题,因此在C++11中,C++引入了指针空值这个概念,为了提高代码的健壮性,在后续表示指针空值的时候建议最好使用nullptr而不是NULL。