C++之剖析内联函数、auto关键字、范围for、指针空值
内联函数
概念*
以inline修饰的函数称为内联函数,例如:
inline int add(int x,int y)
{
return x+y;
}
内联函数能够提高程序运行效率,因为在编译时,编译器是在调用内联函数的地方展开,没有函数压栈的开销。
这时我们会想到,C语言里面的宏函数也有这个功能,并且C++是兼容C语言的,为什么不直接使用宏函数呢?下面将会说宏函数的缺陷部分:
- 宏函数不支持调试;
- 语法比较复杂,容易出错;
- 没有类型安全的检查。
C++为了解决宏函数存在的问题,就推荐有些需要频繁调用的小函数,定义成内联函数,这样函数会在调用的地方展开,没有栈的开销。
但是,内联函数也是有缺陷的,不是所有的函数都需要被定义成内联函数,只有一些指令比较短小的函数才适用被定义成内联函数,若是函数里面含有的指令比较多,这样无疑会加大工作量。
(指令过多,意味着编译出来的可执行程序会变大)
*
总结
- 内联函数是一种以空间换时间的做法,所以当函数代码很长或者有循环、递归函数是不适合使用内联函数的;
- 其实内联函数在编译时就相当于给编译器提建议,减少栈的开销,如果定义的内联函数内有循环、递归等,编译器会进行自动优化,忽略掉内联;
- 内联不建议声明和定义分开,分开后可能会导致链接错误,链接时就找不到内联函数的地址了。
auto关键字
概念
在早期C++中,auto修饰的变量是具有自动存储器的局部变量;
后来,C++中的auto不在只是一个存储类型的指示符,而是作为一个新的类型指示符来指示编译器:auto声明的变量必须由编译器在编译时推到而来。
auto b = a;
//b的类型声明成auto,可根据a的类型自动推导b的类型
auto的使用规则:
-
auto与指针和引用结合起来使用时:用auto声明指针类型时,auto和auuto*无区别,但要是用auto来声明类型时,必须加上&;
-
当在同一行声明多个变量时,变量的类型必须相同;因为编译器实际上只会对第一个类型进行推导,然后再用推导出来的类型定义其他变量。
-
auto不能用作函数参数;
-
不能直接用来声明数组;
范围for
概念
是C++一种新的遍历方法,它会自动取出数组中的元素赋值给变量,直到结束时停止。
范围for的表示分为两部分:第一部分是范围内用于迭代的变量,第二部分是迭代的范围。
for (auto e:arry)
{
cout<<e<<" "<<endl;
}
范围for的出现,一定程度上方便了代码的编写;同时,它与普通循环相类似,用continue结束本次循环,用break跳出循环。
范围for的使用条件
- 迭代的范围必须是明确的;
- 迭代的对象要实现++和==的操作。
指针空值
之前我们定义指针为空都是这样来的:
int* p = NULL;
但实际上,NULL是一个宏,在定义宏的过程中,可能会被定义成字面常量0(#define NULL 0),或者被定义成无类型指针(void*)的常量(#define NULL ((void*)0),所以,C++11中用nullptr来表示指针空值。
int* p = nullptr;
注意:
- 在使用nullptr表示指针空值时,不需要包含头文件,因为它在C++11中是一个关键字;
- 在C++11中,sizeof(nullptr)和sizeof((void*)0)所占字节大小相等。