错误一:引用作函数返回值,但函数中没用static修饰
输出结果:
Q:ret应该是3,为什么再调用一次Add函数后,ret变成了7?
解释:
①:在第二次调用Add函数之前,ret也不一定是三,因为Add的函数结束后,栈帧被销毁,无法确保c的那一块空间是否被清理,没被清理,才是3,被清理了,应该是随机值
解释:在第一次打印ret的时候,发现ret是3,此时函数中c的空间,还未被清理,而再次打印,结果是随机值,此时已经被清理
②: 为什么再调用一次Add函数,先前的ret会变成7?
首先得知道:栈的空间会被不同的函数栈帧重复使用
a:栈帧的创建和销毁:
每次函数调用都会在栈顶创建一个新的栈帧,并在函数返回时销毁它。这意味着,同一个栈内存区域可以被不同的栈帧重复使用。
b:栈帧复用的意义:
节省内存:栈帧的复用意味着不需要为每个函数调用分配新的内存区域,可以节省内存资源。
提高效率:由于栈内存的分配和释放是非常快速的,复用栈帧可以减少内存管理的开销,提高程序的执行效率。
所以,两个相同的函数被前后调用,第一次函数栈帧的空间不仅是被复用,因为函数相同,所以设是被完全的复用,所以当你第二次去调用Add的时候,c的那一块空间和第一次c的空间是一致的,第二次调用函数导致c变成了7,所以先前第一次Add函数的空间被重置成了7
用ret和ret2的地址,来证明是同一块空间
解释:发现两次调用的Add的返回值的空间是一致的,所以在第二次调用之后ret变成了7
③:第二次调用完之后,也不一定是7,取决于编译器是否将空间清理
解释:什么时候清理取决于编译器,不同编译器结果可能不同
总结:出了作用域,不能用引用返回,结果不确定
错误二:static 的定义和初始化写在一行
解释:
①:static修饰的c的特点
静态区的变量具有以下特点:
- 生命周期:静态变量的生命周期从程序开始执行时开始,直到程序结束时才结束。
- 初始化:静态变量在程序启动时进行一次初始化,或者在声明时进行初始化。
- 存储位置:静态变量存储在程序的静态存储区中,这块内存区域在程序执行期间一直存在。
所以,c的空间的确在Add函数结束后还是存在的,但是由2 可知,其c只会被初始化一次,意思是不断地调用Add函数,也不会重复的创建c这个变量,static的这一行只会执行一次,所以,当你把赋值操作也写在static的这一行的时候,受static的影响,赋值操作也只会进行一次
总结:static的定义和赋值不要写在一行
正确写法:static的同时注意分开赋值
总结:把赋值分开写才是正确的写法,即利用了static的特点,又能多次使用函数