目录
1.内联
在调用函数时,其本质就是开辟函数栈帧,每实现一次调用就完成一次开辟和销毁。其实这些在内存世界的行为看来,开辟和销毁都是需要花费时间的。那么如果一个函数中多次调用一个内存较小的函数时,会浪费时间。在C语言中,为了节省时间,要么直接把函数本身写在其中,不去选择通过调用的形式进行使用;要么就是使用宏来写,其作用就是在函数中展开。如果跟上述所说多次调用的话,第一种方法就不太能适用,因为每次调用就写一遍实在是太累了,所以一般用的是宏。但是反过来一想,宏跟函数的区别还蛮大的,宏没有办法像函数一样去判断参数传入的类型并且宏不能被调试,这样显得宏的使用不是很安全。那么C++中,专门有一种函数执行跟宏类似的功能,在函数编译时展开,但是其本质是函数,便完美拥有了函数跟宏的优点。
内联:使用inline即内联,编译时C++编译器会在调用内联函数的地方展开。(debug版本下,内联不会直接展开,毕竟实现是为了让你调试的。在release下会直接展开)
1.怎么设置能在调试时看到
不过在栈帧中可以查看,不过需要设置,在工程点击右键中的属性
2.汇编的具体情况
3.代码膨胀
内联本质是展开,虽然展开能够节省栈帧开辟销毁的时间,但是展开也存在一些内存的问题。假设我这个函数很大,一展开几乎能把寄存器给整“撑”了,要是我调用递归函数写成内联,它不断向下递归那也没完没了了。所以内联适用于小的函数,编译器会自主判断是否要内联,看函数有多大。而上面编译器强行展开大的函数会出现问题的名字叫:代码膨胀。如果这个代码无节制展开,那我们的可执行文件就大了呀;不说别的,我们一个安装包要是都用了内联强制展开,个顶个的内存大到无边,谁还下载的起啊^-^
内联的策略是空间换时间,其代价就是可执行文件变大。
4.内联函数声明与定义不可分离
另外,内联不能定义跟声明分离。会导致链接错误,这是为什么?语法上内联即inline写在函数前面即可,不需要注意,确实不是语法会出错。声明和定义的联系是这样的:首先声明处会有定义的地址,而编译器只要得到声明就会去生成一个符号表然后便不管了,除非调用才会去监测函数定义是否齐全,如果齐全,则跳到对应的地址去进行函数调用。但是内联不同,内联直接展开,因为它是直接展开的,自然设计者不会让它生成符号表,也不会在符号表记录有定义的地址啊,既然定义的地址没有,那不就是没有定义的无效声明嘛,所以链接错误。
2.打印类型
typeid(要识别的类型).name()
3.基于范围的for循环
1.非引用
这里指的是,把e作为容器存储array指针指向的数据。e是临时变量,所以打印e跟数组里的数据没有直接关系,故如果改变e,不能改变数组的数据。
2.引用
4.NULL指针的宏在C++的历史遗留问题
1.问题是什么
在我们看来,NULL指针的类型应该是指针形式的。但是这里我们发现C++的宏定义NULL为数字0。 它会出现下列这种奇怪的错误。编译器就觉得NULL是数字0,去了上一个函数中。(其实应该把NULL定义为void*(0))。这成为了历史包袱,这个bug不能改动,因为改一处动全身啊。所以只能打补丁。
2.补丁是什么
nullptr:C++中真正的空指针。