【发布时间】:2013-09-06 00:30:52
【问题描述】:
给定
int x[10];
int y[10];
int n = 10;
版本 1
int i = 0;
while (i < n)
y[i] = x[i++];
第 2 版
for (int i = 0; i < n; i++)
y[i] = x[i]
这两个版本总是相同的吗?如果不是,它们什么时候不等价?
【问题讨论】:
标签: c arrays for-loop while-loop
给定
int x[10];
int y[10];
int n = 10;
版本 1
int i = 0;
while (i < n)
y[i] = x[i++];
第 2 版
for (int i = 0; i < n; i++)
y[i] = x[i]
这两个版本总是相同的吗?如果不是,它们什么时候不等价?
【问题讨论】:
标签: c arrays for-loop while-loop
这一行:
y[i] = x[i++];
是未定义的行为。您不能在同一语句中使用i 和i++。
您的版本 2,在 for 控制语句中包含 i++,没问题。
【讨论】:
y =4; y = n++ + n++; if一个是遵循优先操作,y的值可能是9,但它甚至可能是8。这就是 C 定义序列点并保证所有side effects 将在继续下一条语句之前发生的原因,即在序列点之后。如果您想在两个序列点之间更改两次值,则不能保证哪个将首先评估,因此这是非法的。
如果我们围绕Greg Hewgill 在他的answer 中正确诊断的未定义行为进行编码,那么我们最终可能会得到如下代码:
int x[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
int y[10];
int n = 10;
i = 0;
while (i < n)
{
if (i % 3 == 0)
continue;
y[i] = x[i];
i++;
//cont: ;
}
for (i = 0; i < n; i++)
{
if (i % 3 == 0)
continue;
y[i] = x[i];
}
由于continue 语句,这些循环是不等价的——事实上,第一个循环是无限循环。并且循环体可以在没有continue 的情况下编写,但我想要一些简单的东西来说明continue 在while 循环和for 循环中的行为。
for 循环运行正常,不会初始化元素 y[0]、y[3]、y[6] 或 y[9],但在其他方面运行良好。
while 循环看起来很相似,但continue; 语句等效于goto cont;,其中cont 是被注释掉的标签,紧挨着右大括号之前。请注意,它会跳过i 的增量,这就是循环“无限”的原因。
所以,如果里面没有continue,这两个循环是等价的。
注意相关循环:
for (int i = 0; i < n; i++)
{
if (i % 3 == 0)
continue;
y[i] = x[i];
}
与第一个 for 循环并不完全相同。变量i 在while 循环和第一个for 循环中的循环外部(之后)可用;当变量在for 循环本身中声明时,它不可用。
【讨论】:
continue 块,在问题中,continue 不存在?
continue 不在问题中。我添加它是为了解释for 循环和while 循环不同的一种情况——当代码不调用未定义的行为时。在其他情况下,如果您避免未定义的行为,则两个循环是“相同的”,正如我也说过的。因此,除非您有 continue 语句,否则 while 循环和 for 循环是等效的。如果您有 continue 语句,它们是不等价的。我还注意到for (i = 0; ...) 和for (int i = 0; ...) 之间的细微差别,这不是问题所在。
i = 0; while (i < n) { y[i] = x[i]; i++; })。如果您的意图是调查未定义行为的好处或其他方面,那么这与您的问题看起来有些不同。
好问题, 看看here 你可以找到一个不错的 c to assembler web 编译器 我比较了两个版本,在循环实现中存在细微的组装差异。 功能似乎完全相同,因此我得出结论,两个样本总是相同的。 而案例: 对于案例:
【讨论】: