C++入门(下)

目录

一、内联函数

二、auto

三、 范围for

四、空指针nullptr


一、内联函数

在C语言中,我们使用宏来对数据进行定义,并且有一些简单一点的函数,也会使用宏来处理,这样可以减少栈帧的消耗,但是这与之而来也会有一些问题

宏的缺点

  1. 宏容易出错,语法有很多坑
  2. 不能调试
  3. 也没有安全检查

比如我们要定义一个加法宏函数

C++入门(下)_第1张图片

必须要给每一个值打上括号,否则当遇到一些优先级必加号还要低的时候,这个函数给到的结果便不是我们想要的。

比如下图

C++入门(下)_第2张图片

这里算出来的结果是1,然而我们想要的(1|2)=  3   (1&1) = 1  加起来应该是4,而这里的结果是1,因为会先运算(2+1) =   3  ,再去运算1|3  的结果再  &  1。

C++为了解决这个坑,提出了更为简便的内联函数

对于一个简单的函数,我们可以再函数前面加上   inline   关键字,使其变成内联函数,当程序调用这个函数不会去call这个函数的地址,而是直接将函数展开,这样没有建立栈帧,速度自然也就变快了

但是内联函数也有他的缺点, 如果函数很大,便不适用与内联,因为在编译过程中,内联函数会被展开,如果一个函数被调用了100次,那么也会展开一百次,函数简单一点还好,不会大到哪里去,但如果很大,汇编代码会变得非常冗余,会发生代码膨胀现象,但也无需担心,编译器会帮我们处理,当函数大于10行时,如果你仍要使用内联函数,编译器会自动忽视掉  inline  的存在,把它当做普通函数 ,call 他的地址就好。

还有一点,内联函数不能声明和定义分离,引文内联函数需要展开,因此他不会在符号表里存放他的地址。

二、auto

auto是一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto 的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。

说人话就是他会自动推导变量的类型(必须初始化才能使用)。

C++入门(下)_第3张图片

虽然一些简单的不是很需要auto关键字,但是当我们学到C++后续内容是,会有迭代器的概念,迭代器的类型是很长一串的,要输入他的类型会很累。 

C++入门(下)_第4张图片

如果使用auto,编译器会自动推导他的类型, 

C++入门(下)_第5张图片

我们这样可以使代码更加简洁,当然,auto不很像我这样的新手去使用,不然会比较难理解他的类型,还是要多多输入他本身的类型,熟悉了之后再使用auto会更好!

 auto对于指针来讲 auto 和 auto*并没有什么区别,只是auto声明引用类型时则必须加&

在函数中,不用使用auto去修饰参数的类型,因为编译器无法对 auto 的实际类型进行推导。

三、 范围for

在C++11中,出了一个基于范围的for循环,他能让我们很方便的取出数组或者其他STL容器内所存放的元素,范围for可以配合上面的auto进行使用。

C++入门(下)_第6张图片

这看来是不是比之前的代码简单太多了。

int arr[] = { 1,2,3,4,5,6,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i=0;i

注意:范围for只是将数组或容器等的元素取出来,并不会影响原来的值,如果需要修改原来的值,可以加上&(引用)

 C++入门(下)_第7张图片

C++入门(下)_第8张图片

四、空指针nullptr

在C++11之前的版本中,C++将 NULL 定义为了0。

但是这样也会发生一些问题 

C++入门(下)_第9张图片

比如上图这种,f(NULL)我们想去调用f(int*)函数,却调用了f(int) 函数,C++11为了避免这个坑,又推出了nullptr  

C++入门(下)_第10张图片

 使用nullptr来代表空指针更为合理

你可能感兴趣的:(c++,开发语言)