【发布时间】:2010-09-28 13:32:20
【问题描述】:
for(int i=0 ; i++ ; printf("%d",i));
printf("%d",i);
输出为 1。 如果我们让 i = 1 则有一个荒谬的输出,如果 i = -1 则输出为 01。 For 循环是如何工作的?
【问题讨论】:
for(int i=0 ; i++ ; printf("%d",i));
printf("%d",i);
输出为 1。 如果我们让 i = 1 则有一个荒谬的输出,如果 i = -1 则输出为 01。 For 循环是如何工作的?
【问题讨论】:
for循环的测试部分是i++。
因为++(或增量)是post-fix(写在变量之后,而不是之前),增量发生在在评估语句之后并经过测试。测试在 0 上进行,其评估结果为 FALSE,因此“循环”存在而从未运行过。
接下来,后缀++ 生效,将i 从0 更改为1。
正如@paxdiablo 指出的那样,一旦循环退出,i 就超出了范围。
无论最终 printf 打印的是什么,它都是一个不同的 i,声明并给出了一个未在您的代码中显示的值。
在其他情况下,如果你从 1 开始 i,那么测试总是正确的,并且每个数字都被打印出来(直到 i 溢出,并返回到 0)。
最后,如果i 从 -1 开始,则测试最初通过(-1 为 TRUE),发生后修复增量,将 -1 变为 0,并打印 0
循环再次运行,这次 0 测试失败,循环结束,后修复增量发生,另一个i(未在您的代码中显示)在循环结束后打印出来。
【讨论】:
i 只存在于for 的范围内。无论i 在循环之后被打印出来是一个不同的 (在for 循环运行时隐藏)。循环对该变量的影响为零。
i,这会使这段代码成为一个有用的测试用例,尽管我当然希望人们不必处理这样的问题一个编译器!
for 循环甚至不会运行 - i 在条件下测试时为 0,before 被递增。此外,除非i 也在循环之前的某处定义,否则代码将无法编译,因为printf 中的i 在循环之后是未定义的。
您到底是从哪里获取此代码的?这是编写for 循环的一种非常怪诞的方式,我永远不会在混淆编码竞赛之外使用它。
【讨论】:
i 不会增加,但它也会立即超出范围,所以就像森林中那棵众所周知的树听到倒下;-)
它不应该编译,除非之前声明了 i。
代码在 C90 中是非法的,因为除了块的开头之外不允许声明。在 C99 中,i 在 for 循环中的声明是合法的,但它的范围是循环,并且不会超出它。这在标准 C++ 中也是如此,但在准标准 C++ 中,范围确实扩展到封闭块的末尾。当然,有可能编译器不符合任何已发布的标准,在这种情况下,我们不能说绝对会发生什么。
for 循环有三个子句。第一个在最开始运行,没有其他地方,并且(在 C99 和 C++ 中)可能是一个声明。它建立i的起始值。
第二个子句在循环体之前运行。如果计算结果为 false,for 语句将立即结束。由于i 是int,唯一的假值为0。在这种情况下,i++ 返回i 的当前值并将其递增以供以后使用。因此,如果i 为 0,则 for 循环什么也不做。如果i 为1,则i 将递增,直到i 为0 或发生其他情况。这实际上是未定义的行为,因为i 是有符号整数类型,但通常会发生的情况是它会递增到可能的最正值int,然后变成可能的最负值int,然后递增直到它是 0 并且循环停止。如果 i 从 -1 开始,那么在第一次运行时它不是 0,但在第二次运行时会是。
这里执行打印的第三个子句在循环体之后运行。它通常用于递增循环正在执行的任何操作,它可能在整数范围内运行,或者在链表中的指针链或其他内容中运行。除了被执行之外没有任何作用。
for 循环的主体为空,如右括号后紧接的; 所示。这意味着,在执行第一个子句后,将交替执行第二个和第三个子句,只要第二个子句的计算结果为 0,就会停止。
这是一个非常奇怪的for 语句,因为没有循环体,并且在第二个子句中完成了增量,但它是合法的(除非存在算术溢出,如果i 开始为正,则会发生这种情况)。紧随其后的未定义 i 不是。
【讨论】:
在for(int i=0 ; i++ ; printf("%d",i)); 中,测试条件为假(因为i++ 返回0),循环不会运行。
注意循环后面的分号。 :)
【讨论】:
这看起来像是乱码。我不敢相信这是故意的。
for() 语句的第二部分指定循环终止的条件。如果条件为真,则循环结束,否则循环。
在这种情况下,语句的第二部分是i++。这通常在 if() 语句的第三部分。通过放入第二部分,您将强制循环仅在i++ 评估为假(即零)时退出。因此,如果i 开始小于零,您将获得迭代直到它达到零,否则您将获得一个无限循环。
正如我所说,++ 通常在语句的第三部分,所以从表面上看,好像有人删除了 if() 语句的中间部分,出现编译错误,并且试图通过在最后卡住 printf() 来修复它。凌乱。
【讨论】:
此循环在 i 为 0 时结束。因此,如果您从 0 以上开始,则 i 将在 2^31 或 2^63 次迭代后为 0...。
【讨论】:
++ 用作后增量。因此,当您测试 i 的值时,它将是 0 并且您根本不会进入循环。在循环之外打印i 的值,现在是1
【讨论】:
for(int i=0 ; i++ ; printf("%d",i)); printf("%d",i);
等价于
int i = 0;
while (i++)
{
printf("%d",i);
}
printf("%d",i);
当 i = 0 最初时,i++ 为 0(因此为假),因此循环永远不会被执行。但是我被设置为 1,所以最后一个 printf 打印 1。
最初当 i = -1 时,i++ 为 -1(非零,所以为真),因此循环体执行。在 i++ 之后,i 为 0,所以第一个 printf 打印 0。我们现在已经将问题简化为前一种情况,所以剩下的输出是 1。所以整体输出是“01”,0 和 1彼此相邻,因为您没有在 printf 格式字符串中添加任何空格。
当 i = 1 最初时,循环执行 i = 1,然后 i = 2,然后 i = 3,...,然后 i = 2147483647(或任何INT_MAX),然后环绕到i = -2147483648,然后 i = -2147483647,然后 i = -2147483646,最终在打印了数十亿个数字后返回到 0。
【讨论】:
i 在第二个printf 中打印什么,都不是在第一个中打印的(其范围仅限于for 本身)。除此之外,还不错。更好的是像`{ int i = 0; while (i++) { printf("%d",i); } } printf("%d",i);
printf 中的 i 不是循环中的 i。