C 函数和变量的范围

C++ functions and scope of variables

本文关键字:范围 变量 函数      更新时间:2023-10-16
#include<iostream>
using namespace std;
void fun(int a) {
    int x;
    cout << x << endl;
    x = a;
}
int main() {
    fun(12);
    fun(1);
    return 0;
}

此代码的输出如下:

178293 //garbage value
12

为什么我们要获得12而不是垃圾值?

为什么我们要获得12个而不是垃圾价值?

从理论上讲,x的价值可能是任何东西。但是,实践中正在发生的事情是,一个接一个的呼叫fun一个接一个地造成x的先前值仍在堆栈框架上。

假设堆栈框架的结构如下:

 arguments
 return value
 local variables

在您的情况下,

用于参数的内存等于sizeof(int)
由于返回类型为 void,因此编译器可以使用任何内存省略返回值。
用于本地变量的内存等于sizeof(int)

第一次进行函数调用时,参数部分中的值设置为12。局部变量中的值是垃圾,如您所知。但是,在从功能返回之前,您将本地变量的值设置为12。

第二次制作函数,参数的值设置为1。本地变量中的值仍来自上一个呼叫。因此,它仍然是12。如果您第三次调用该函数,则可能会在本地变量中看到值1。

无论如何,这是一个合理的解释。再一次,请记住这是不确定的行为。不要指望任何特定的行为。编译器可以在使用之前决定擦洗堆栈框架。编译器使用后可以决定立即擦洗堆栈框架。使用后,编译器可以在使用堆栈框架后做任何事情。如果对fun的调用之间有另一个调用,您很可能会得到完全不同的值。

打印时尚未初始化值 x。从非初始化的记忆中读取是ub,,即。,无法保证会发生什么。它可以输出一个随机数,或者调用不太可能会做一些意外的位组合。

读取非专业化整数是UNDEFINED BEHAVIOR,这意味着它可以从字面上做任何事情,可以打印任何东西。它可以格式化您的硬盘驱动器或折叠可观察到的宇宙!基本上,我不知道这样做的编译器实现,但是从理论上讲,它们可以!