1.内联函数
顾名思义,内联函数也是函数的一种,我们在C语言的学习过程里面知道了函数和宏之间的区别和各自的优缺点;
函数的使用需要建立栈帧,宏的使用需要考虑各种符号的优先级问题,很容易出错,因为宏在使用的时候就是简单的替换,可能不会按照我们想要的计算顺序;
内联函数就是在我们平常的函数前面加上inline关键字,这个内联函数在使用,定义的时候和函数的区别就是,内联函数会在调用的时候,会在调用函数的地方直接进行内联函数的展开,不会建立栈帧(这个也是内联函数存在的原因,因为肯定要有自己的特定功能);
内联函数需要注意很多地方:
(1)我们在定义内联函数的时候,不能把内联函数的定义和声明写在不同的文件里面(这个涉及到编译链接的相关知识),否则就会出现链接错误,因为内联函数不会建立栈帧,不会有自己的地址,就不会到符号表里面,链接的时候在符号表里面找不到,就会出现链接错误;
(2)内联函数即使我们进行定义,这个不是我们说的算的(就算你在函数的前面加上inline这个关键字),编译器在进行编译的时候是会进行审核的,如果我们对某些函数,比如这个函数的函数体特别长,或者是递归函数,即使我们加上inline,编译器还是会按照普通的函数进行处理的,我们一般对于比较短的函数进行设置内联,因为内联函数调用的时候会进行展开,函数体特别长,调用次数特别多的话,每次都要展开,就会造成代码的膨胀,这样就得不偿失了。
2.auto关键字
这个关键字就是进行类型的自动匹配:
下面的typeid.name()就是进行类型的识别;
但是在普通的场景里面,它的用处不大,我们在学习vector的时候,可以使用这个关键字进行代码的简化;
此外,auto不能用来进行定义数组,不用用来作为函数里面的参数的类型,希望读者知悉。
3.范围for
范围for就是用来遍历我们的数组的,我们之前在遍历数组的时候,是这样搞得:
当你学会了范围for之后,我们的数组遍历可以这样写:
是不是很方便,这里浅浅的解释一下自己的理解:我们的auto就是一个类型的识别,我们这里的auto完全可以使用int进行代替,因为这里我们的数组就是int类型的数据,但是如果是其他的double等类型呢?我们使用auto相当于是一个万能胶,什么类型的数组成员都是可以使用这个循环的;
我们的这个e相当于就是一个遍历过程里面的中间变量,我们数组里面的元素传递给e,然后进行打印输出e的结果,这个过程数组什么时候结束,循环执行了多少次,我们都不需要关心,因为这些编译器会解决;
下面我们再看一个现象:
这里,我们显然是想让数组里面的每个数字都乘以2,但是打印的结果却并不是我们想要的,这个原因就是我们的e就是一个中间变量,e的改变并不会影响我们的数组里面的元素的值,如果我们想要实现这个功能使用引用就可以了,这个时候的e就是别名,相当于指针,变化就会同步到我们的数组元素上面去了:
4.nullptr
这个也是C++相对于C语言的改进之处,我们的NULL实际上在标准库里面就是被宏定义为0:
因此我们使用函数的重载调用函数的时候,NULL会被当做int类型,而不是指针类型;
但是nullptr可以解决这个问题,因此我们在C++里面通常使用nullptr而不是NULL。