#include <stdio.h>
int main()
{
for(int i=0;i<100;i++)
{
int count=0;
printf("%d ",++count);
}
return 0;
}
上述程序的输出为:一一一一一一
请看一下上面的代码。我在for循环中声明了变量“int count=0”。据我所知,变量的作用域在块内,所以count变量将在for循环执行之前一直有效。“int count=0”执行了100次,那么它必须创建变量100次,否则它必须给予错误(重新声明计数变量),但它不是这样发生的-可能是什么原因?
根据输出,变量每次初始化为零。
请帮我找出原因。
4条答案
按热度按时间6mw9ycah1#
这样简单的代码可以在http://www.pythontutor.com/c.html上可视化,便于理解。
回答你的问题,
count
在超出作用域时被销毁,也就是循环的结束}
。在下一次迭代中,创建一个同名变量并初始化为0,由printf
使用。如果计数是您的目标,请打印
i
而不是count
。7eumitmz2#
C标准使用计算机的抽象模型来描述C语言。在这个模型中,
count
在每次执行循环的主体时被创建,并且在主体的执行结束时被销毁。通过“创建”和“销毁”,我们意味着为它保留内存并且释放内存,并且使用该保留来执行初始化。C标准并不要求编译器盲目地实现这个模型,大多数编译器在例程开始时会分配一个固定数量的堆栈空间,
count
的空间包含在这个固定数量中,然后count
在每次迭代中都使用这个相同的空间,然后,如果我们查看生成的汇编代码,我们将不会看到任何内存的保留或释放;对于整个例程,堆栈将仅增长和收缩一次,而不是在每次循环迭代中增长和收缩。因此,答案是双重的:
count
的新生命周期在每次循环迭代中开始和结束。count
保留一次,尽管实现也可以在每次迭代中分配和释放内存。然而,即使你知道你的C实现在可能的情况下只为每个例程分配一次堆栈空间,你也应该从这方面考虑C模型中的程序。
在这段代码中,编译器可能会分配4个字节的堆栈空间给**
count
和x
使用,一次只给其中一个使用。例程在启动时将堆栈增长一次,包括用于count
和x
的4个字节。在循环的每次迭代中,它将首先为count
使用内存,然后为x
使用内存。这让我们看到内存首先为count
保留,然后释放,然后为x
保留,然后释放,然后在每次迭代中重复。保留和释放在概念上发生,即使没有指令来增长和收缩堆栈。另一个有启发性的例子是:
在这种情况下,编译器无法在例程启动时为
a
和b
保留内存,因为它不知道它需要多少内存。在每次迭代中,它必须调用baz
以确定a
需要多少内存以及b
需要多少内存,然后必须分配堆栈空间(或其它存储器)。此外,由于大小可随迭代而变化,a
和b
不可能在每次迭代中都在同一位置开始它们中的一个必须移动以便为另一个让路。因此,这段代码让我们看到,必须在每次迭代中创建一个新的a
和一个新的b
。af7jpaap3#
int count=0
执行100次,则必须创建变量100次不,它 * 定义 * 变量
count
一次,然后 * 赋予 * 它值0
100次。OP的示例可以重写为完全等效的形式,如下所示。
9jyewag04#
Eric是正确的。在更短的形式:
通常计算机在编译时决定一个函数需要多少内存以及变量在堆栈中的位置。堆栈内存没有单独的分配/释放。
此外,当变量嵌套在{大括号}中时,一旦执行离开了大括号集,编译器就可以自由地将内存重新用于函数中的其他变量,我有意这样做有两个原因:
示例: