我正在学习 C,并在我正在阅读的书中看到了下面列出的第一个循环。我很好奇两者之间的区别是什么,因为我习惯于使用第二个并且即使它们返回不同的结果也无法弄清楚它们之间的区别。
for(i = 0; i < 10; ++i){}
for(i = 0; i <= 10; i++){}
我正在学习 C,并在我正在阅读的书中看到了下面列出的第一个循环。我很好奇两者之间的区别是什么,因为我习惯于使用第二个并且即使它们返回不同的结果也无法弄清楚它们之间的区别。
for(i = 0; i < 10; ++i){}
for(i = 0; i <= 10; i++){}
第一个迭代到9
,第二个迭代到10
。就这样。
前/后增量操作没有区别。
为两个版本生成的未优化代码:
for(int i = 0; i < 10; ++i)
00E517AE mov dword ptr [i],0
00E517B5 jmp wmain+30h (0E517C0h)
00E517B7 mov eax,dword ptr [i]
00E517BA add eax,1
00E517BD mov dword ptr [i],eax
00E517C0 cmp dword ptr [i],0Ah
00E517C4 jge wmain+53h (0E517E3h)
{
}
for(int i = 0; i <= 10; i++)
00E517E3 mov dword ptr [i],0
00E517EA jmp wmain+65h (0E517F5h)
00E517EC mov eax,dword ptr [i]
00E517EF add eax,1
00E517F2 mov dword ptr [i],eax
00E517F5 cmp dword ptr [i],0Ah
00E517F9 jg wmain+88h (0E51818h)
{
}
因此,即使在这里,也没有性能损失。i++
比这慢的事实++i
是不正确的(至少在这种情况下,它没有任何区别)。例如,它会更慢int y = i++
,但在这种情况下,两者会做不同的事情,这里不是这种情况。性能问题可能在 20 年前的编译器上仍然有效,但现在不再有效。
在第一个你有预增量,第二个有一个后增量。
唯一的问题是条件,即第一次检查最多 9 次,第二次检查最多 10 次。
在这两个循环中,增量运算符在这种情况下没有任何区别
当您在分配值时使用它们时,前/后增量操作将起作用。
说
i=10;
j = i++;
这里的值i
将是 11,但是,值j
将是 10。因为在将值分配给即 Post Incrementi
后将递增j
i=10;
j = ++i;
这里的值i
将是 11,值j
也将是 11。因为i
在值被分配之前会递增,j
即 Pre Increment
第一个将运行 10 次。第二个将运行 11 次。
大多数人已经说过迭代次数相差一,并且前后增量在这里没有任何区别。
对于 c,我会说第一个循环是您更常遇到的。我认为这样做的原因是 c 使用从零开始的数组,因此数组(或字符串,因为这是一个字符数组)的最大值不用作数组中的索引(这将超出范围)。因此,在此示例中循环遍历长度为 10 的数组时,第一个循环将是更合乎逻辑的循环,因为您可以安全地i
用作数组的索引。第二个循环将导致错误(可能是分段错误)。
你说你习惯了第二个。我不知道你为什么习惯了这一点,但我假设其他一些编程语言或者在数学中,循环(求和等)运行到极限(但通常从一个开始)。在这种情况下,从零开始的索引可能会有点令人沮丧。
简而言之,根据我的经验,您会更频繁地发现第一个循环,但第二个循环有很多用例。
至于++i
vs i++
:我倾向于后者,因为 for 语句的这一部分发生在循环的末尾。因此,后缀符号感觉更合乎逻辑。但再一次,这并不重要。