有什么区别(记忆明智):
for(int x=0;x<100;x++)
{
int y = 1+x;
}
和
int y = 0;
for(int x=0;x<100;x++)
{
y = 1+x;
}
我一直想知道它们是否相同或者首先是浪费记忆?...
答案 0 :(得分:20)
记忆方面,没有区别。 y在堆栈中,无论它在方法中声明了什么。这里唯一的区别是y的范围:在第二种情况下,它仅限于for循环的主体;在第一个,它不是。这纯粹是在语言层面:再次,y以完全相同的方式分配,即在堆栈上。
为了清楚地说明这一点,这是一个代码示例:
void method1() {
for (;;) {
int a = 10;
}
}
void method2() {
int a;
for (;;) {
a = 10;
}
}
以下是在两种情况下以调试模式生成的汇编程序:
# method1()
00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 cmp dword ptr ds:[00662E14h],0
0000000b je 00000012
0000000d call 5D9FE081
00000012 xor edx,edx
00000014 mov dword ptr [ebp-4],edx
00000017 mov dword ptr [ebp-4],0Ah
0000001e nop
0000001f jmp 00000017
# method2()
00000000 push ebp
00000001 mov ebp,esp
00000003 push eax
00000004 cmp dword ptr ds:[002B2E14h],0
0000000b je 00000012
0000000d call 5ED1E089
00000012 xor edx,edx
00000014 mov dword ptr [ebp-4],edx
00000017 mov dword ptr [ebp-4],0Ah
0000001e nop
0000001f jmp 00000017
即使不了解任何关于装配的知识,您也可以看到两种方法具有完全相同的指令。换句话说,在声明a的位置,没有任何反应。
然而,如果你使用任何具有构造函数的类型,例如std :: vector:有一个重要的区别,那么在构造函数被声明时,会调用构造函数,所以如果你在循环中声明它,它将在每次循环时重建。例如:
for (/* index */) {
std::vector<int> a; // invokes the constructor of std::vector<int> everytime
} // destructor called each time the object goes out of scope
std::vector<int> a; // constructor only called once
for (/* index */) {
}
如果您使用new,情况会变得更糟:这两段代码表现得非常不同:
for (/* index */) {
char *a = new char[100]; // allocates 100 additional bytes every time !
} // must remember to delete[] a in the loop, otherwise it's a memory leak !
//////
char *a = new char[100]; // only one allocation
for (/* index */) {
}
答案 1 :(得分:6)
它们占用的内存量完全相同 - sizeof(int)
个字节;第一个没有使y
在大括号外可见,第二个大括号。在任何一种情况下都没有浪费(假设在两种情况下在}
之前都有更多的代码; - )。
答案 2 :(得分:1)
一个好的编译器 - 或者至少一个打开优化的编译器 - 可能会执行后者。
答案 3 :(得分:1)
与现代编译器无关。代码将(在大多数情况下)优化为第二个样本。即使它没有,每次声明y时(在第一个例子中)都是一次推送,当'for'括号结束时弹出,所以它不浪费内存,尽管它可能浪费一些CPU周期。但是我们现在有很多可用的东西:)
答案 4 :(得分:0)
它们在功能和内存使用方面都是等效的。
如果循环后函数中有更多代码,后者可能在该函数调用的其余部分(sizeof(int)bytes)的持续时间内占用更多堆栈空间,具体取决于定义了其他局部变量和编译器优化设置。
但是对于所有意图和目的而言,两者都与你选择的无关紧要点相同;选择最适合您的编码指南/标准/品味的那个。
答案 5 :(得分:0)
写的一个重要区别:如果你做了
for(int x=0;x<100;x++)
{
int y = 1+x;
}
z = y-3; // <=== ERROR!
你无法在for循环之外访问y。
使用时
int y = 0;
for(int x=0;x<100;x++)
{
y = 1+x;
}
z = y-3; // <=== OK
y
继续在封闭范围内显示。