函数中的变量是否可能保存C中函数的旧调用中的旧值?

函数中的变量是否可能保存C中函数的旧调用中的旧值?,c,memory,C,Memory,我有这样的经历: void test(int iter){ int i; if(iter>3){ i=5; printf("%d",i); }else{ printf("%d",i); } return; } int main(){ test(5); test(2); return 1; } 这只是一个例子。当主变量i调用时,如果至少iter大于3,是否可能保持

我有这样的经历:

void test(int iter){    
  int i;    
  if(iter>3){    
    i=5;    
    printf("%d",i);    
  }else{    
    printf("%d",i);    
  }    
  return;    
}
int main(){
  test(5);
  test(2);
  return 1;
}
这只是一个例子。当主变量
i
调用时,如果至少
iter
大于3,是否可能保持值5(内存中)?
我知道这是不正常的。但是我的程序中有一个函数(我没有做这个的静态变量)可以完成这个任务。那么每次初始化这个变量的地址是否相同(所以我得到的是旧值)?或者发生了什么?我不想持有旧的价值观或其他东西。我只是好奇:这怎么可能?

如果
I
存储在堆栈上的某个位置,并且该位置未被修改,那么
I
将保留其值


假设
i
甚至存储在堆栈上(优化可能会消除这一点),如果存在使用堆栈的中断(或者可能是由于时间片导致的上下文切换),堆栈指针下方的堆栈区域将被覆盖。某些编译器可能会填充堆栈区域,通常是在调试模式下。Visual Studio在调试模式下将使用上述代码捕获未初始化变量的用法。

如果
i
存储在堆栈上的某个位置,并且该位置未被修改,则
i
将保留其值


假设
i
甚至存储在堆栈上(优化可能会消除这一点),如果存在使用堆栈的中断(或者可能是由于时间片导致的上下文切换),堆栈指针下方的堆栈区域将被覆盖。某些编译器可能会填充堆栈区域,通常是在调试模式下。Visual Studio在调试模式下将使用上述代码捕获未初始化变量的用法。

在您向我们展示的示例中,您从未使用值初始化i,并且除非iter大于3,否则它从未被赋值

在您实际将其设置为某个值之前,它的值是未定义的,而您仅在“if then else”子句的“if”部分执行此操作


因此,当iter小于等于3时,i中可能有一个垃圾值是完全正常的。

在这个示例中,您向我们展示的是,您从未使用值初始化i,并且除非iter大于3,否则它从未被赋值

在您实际将其设置为某个值之前,它的值是未定义的,而您仅在“if then else”子句的“if”部分执行此操作


因此,当iter小于等于3时,i中可能有一个垃圾值是完全正常的。

清除变量Global(函数失效)。 例如:

int a=0;
void f(){
    a++; 
}

这样,在执行函数后,值不会丢失。

清除变量全局(函数失效)。 例如:

int a=0;
void f(){
    a++; 
}
这样,在执行函数后,值不会丢失。

注意
static int i中的static关键字行。


注意
static int i中的static关键字行。

这是您正在经历并发现的错误行为,还是您想要创建的行为?这是未定义的行为,因此显示的值可以是任何内容(或无内容或崩溃)。一种解释行为的方法是这样一个著名的SO答案:您正在经历的行为是一个错误,还是您想要创建的行为?这是未定义的行为,因此显示的值可以是任何内容(或任何内容或崩溃)。对这种行为进行推理的一种方法是这样一个著名的答案:首先,不是问题的重点。OP想要知道行为的解释,而不是存储变量的方法。其次,如果变量是函数的局部变量,则选择静态变量比全局变量更好。首先,这不是问题的重点。OP想要知道行为的解释,而不是存储变量的方法。其次,如果变量是函数的局部变量,则静态变量比全局变量更好。因此,如果在调用后,“i”的值作为垃圾在堆栈上,并且如果堆栈的这个地址不会被使用(由其他东西初始化),则在这种情况下,我的下一次测试调用将打印5。如果我没有初始化,但在与以前相同的地址中定义,并打印实际上是5的垃圾。是这样吗@rcgldr@Theredone-根据选项的不同,
i
甚至可能不存储在堆栈上,而是替换为代码中的立即值。假设
i
在堆栈上,则中断或上下文切换(时间切片)可能会修改
i
的存储位置。如果
i
存储在堆栈上,并且该位置的值没有任何变化,则
i
的值将被保留。因此,如果调用后,“i”的值作为垃圾存储在堆栈上,并且如果堆栈的此地址不会被使用(由其他内容初始化),则在这种情况下,我的下一次测试调用将打印5。如果我没有初始化,但在与以前相同的地址中定义,并打印实际上是5的垃圾。是这样吗@rcgldr@Theredone-根据选项的不同,
i
甚至可能不存储在堆栈上,而是替换为代码中的立即值。假设
i
在堆栈上,则中断或上下文切换(时间切片)可能会修改
i
的存储位置。如果
i
存储在堆栈上,并且该位置的值没有任何变化,则
i
的值将被保留。每次初始化一次后,我都会得到5。即使iter小于3。但是每一次。所以我试图理解这是怎么可能的。一次5分可能会发生,但每次都有点奇怪。不,其实不是。它可能是在不同设备上运行的不同值。它可能每次都是一样的,它是“未定义的”,你不知道编译器是如何编写的。在初始化一次之后,我每次都得到5分。即使iter小于3。但是每一次。所以