这是我昨晚写的一个非常小的程序:
void testWithFunction(int val) {
int someA;
printf ("SomeA: %x %d \n ", &someA, someA);
someA = val;
}
int main() {
int j = 5;
while ( j-- ) {
int i;
if ( j == 4) { i = 10; }
printf("i: %x %d \n", &i, i);
}
testWithFunction(5);
testWithFunction(10);
testWithFunction(0);
// system("pause");
return 0;
}
上面的输出是:
i: 28ff20 10
i: 28ff20 10
i: 28ff20 10
i: 28ff20 10
i: 28ff20 10
SomeA: fffffffe 2686916
SomeA: 5 2686916
SomeA: a 2686916
我曾经认为在循环内声明的变量具有局部范围 - 它们在循环终止时被销毁。对于每个新迭代,将再次创建其所有局部变量。但是在这个例子中,似乎每次都重复使用相同的变量,因此,变量甚至可以记住它的最后写入值。这同样适用于函数 - 函数本地的变量应该在函数终止时被销毁,并且应该在再次调用函数时重新创建!但是,结果表明变量的行为就像使用static关键字声明它们一样!这对我来说是新鲜事。请纠正我 - 静态关键字是否隐含所有变量?
我尝试过与结构类型节点相同的事情并找到相同的结果。所以我认为我们不应该假设变量被重新分配到相同的内存空间,因此它们保留了它们的价值。 (我同意“破坏”并不会实际删除旧值)
示例2:
#include <stdio.h>
typedef struct node
{
int val;
struct node *next;
}node;
int main()
{
int i;
node newtemp,root,temp;
scanf("%d",&i);
while(i--)
{
node array[i];
node n;
int j;
for(j = 0; j < i; j++) {
printf (" array: %x ", &array[j] );
}
n.val = i;
n.next = NULL;
printf("node: %x\n", &n);
}
return 0;
}
输出:
4
数组:28feb0数组:28feb8数组:28fec0节点:28ff00
数组:28fec0数组:28fec8节点:28ff00
数组:28fec0节点:28ff00
节点:28ff00
答案 0 :(得分:2)
这里有一个未定义行为的经典案例。
When will memory used in a function become free ??(C programming)
编辑:您的编辑仍显示未定义的行为。仔细阅读堆栈框架。您遇到的问题是由于循环中的堆栈帧与之前循环中的堆栈帧大小相同。因此,n总是占用堆栈中的相同空间。永远不要依赖这样的行为,主要是因为它未定义。同样,编译器可以通过各种有趣的方式自由地优化它,这可能会,也可能会彻底破坏您的代码。
答案 1 :(得分:2)
在使用本地变量someA
之前,您没有初始化它。这是Undefined Behaviour。一切顺利。
答案 2 :(得分:2)
你的代码更多的是基本上只是重复做同样的事情。每次调用testWithFunction()
时,它都会在堆栈上为someA
int分配一些空间。偶然的,你总是得到堆栈空间的SAME块,所以看起来你的变量是静态的。但这只是偶然的机会副作用。
如果您调用了另一个函数或者做了影响堆栈的ANYTHING,您会看到值随机变化。
答案 3 :(得分:1)
printf ("SomeA: %x %d \n ", someA);
有一个错误,
您正在打印两个值但只提供一个值。可能之前的值恰好在someA之后恰好位于堆栈上,因此printf会读取它。