这个C代码背后的逻辑是什么?

时间:2010-09-28 13:32:20

标签: c logic

for(int i=0 ; i++ ; printf("%d",i));
printf("%d",i);

输出为1。 如果我们使i = 1,则存在荒谬的输出,如果i = -1,则输出为01。 For循环如何运作?

8 个答案:

答案 0 :(得分:14)

for循环的测试部分是i++

因为++(或增量)是后修复(写在变量之后而不是之前),所以在语句之后发生增量进行评估和测试。测试在0上,其评估为 FALSE ,因此“循环”存在而不会被运行。

接下来,修复后的++生效,将i从0更改为1.

正如@paxdiablo所指出的,一旦循环退出,i超出了范围。 无论打印的最终printf是什么,它都是一个不同的i,声明并给出一个未在代码中显示的值。


在其他方案中,如果从1开始i,则测试始终为true,并打印出每个数字(直到i溢出,并返回0)。


最后,如果i从-1开始,测试最初通过(-1为 TRUE ),则会发生修复后增量,将-1变为0,然后为0打印出来。

循环再次运行,此时0未通过测试,循环结束,发生修复后增量,另一个i(代码中未显示)在结束后打印出来循环。

答案 1 :(得分:6)

for循环甚至不会运行 - i在条件下进行测试时为<0>,递增之前。此外,除非在循环之前的某处定义i,否则代码将无法编译,因为} 循环之后的i未定义。< / p>

你到底在哪里接受这个代码?编写printf循环是一种非常奇怪的方式,我绝不会在混淆的编码竞赛之外使用它。

答案 2 :(得分:3)

它不应该编译,除非先前声明了i

代码在C90中是非法的,因为除了块的开头之外没有允许声明。在C99中,i循环中for的声明是合法的,但其范围是循环,并不超出它。这在标准C ++中也是如此,但在预标准C ++中,范围确实延伸到封闭块的末尾。当然,编译器可能不符合任何已发布的标准,在这种情况下,我们不能说绝对应该发生什么。

for循环有三个子句。第一个是在最开始运行而在其他地方运行,并且(在C99和C ++中)可能是一个声明。它确定了i的起始值。

第二个子句在循环体之前运行。如果计算结果为false,则for语句立即结束。由于iint,因此唯一的错误值为0.在这种情况下,i++会返回当前值i并将其递增以供以后使用。因此,如果i为0,则for循环不执行任何操作。如果i为1,则i将递增,直到i为0或其他情况发生。这实际上是未定义的行为,因为i是一个带符号的整数类型,但通常会发生的是它会增加到最可能的int,然后变成最可能的负int然后递增,直到它为0并且循环停止。如果i从-1开始,那么在第一次运行中它不是0,但它将用于第二次运行。

这里执行打印的第三个子句在循环体之后运行。它通常用于递增循环所做的任何事情,这可能是通过一系列整数或链接列表中的指针链或其他东西来运行的。它除了被执行外没有任何效果。

for循环的主体为空,如右括号后的;所示。这意味着,在执行第一个子句之后,执行将是第二个和第三个交替,只要第二个子句的计算结果为0就会停止。

这是一个非常奇怪的for语句,因为没有循环体,增量在第二个子句中完成,但它是合法的(除非有算术溢出,如果i为正则会发生这种情况开始)。紧随其后的未定义i不是。

答案 3 :(得分:1)

for(int i=0 ; i++ ; printf("%d",i));中,测试条件为false(因为i++返回0),循环将不会运行。

注意循环后的分号。 :)

答案 4 :(得分:1)

这看起来像是错误的代码。我无法相信这是故意的。

for()语句的第二部分指定循环终止的条件。如果条件的计算结果为true,则循环结束,否则迭代。

在这种情况下,声明的第二部分是i++。这通常位于if()语句的第三部分。通过放入第二部分,您强制循环仅在i++求值为false时退出,即为零。因此,如果i开始小于零,您将获得迭代直到它达到零,否则您将获得一个infinte循环。

正如我所说,++通常位于语句的第三部分,所以从表面上看,似乎有人删除了if()语句的中间部分,得到了编译错误,并试图通过干扰最后的printf()来解决它。凌乱。

答案 5 :(得分:0)

i 为0时,此循环结束。因此,如果从0开始,我将为0 ...在2 ^ 31或2 ^ 63次迭代之后。

答案 6 :(得分:0)

++用作后期增量。因此,当您测试i的值时,它将为0并且您根本不会进入循环。在循环外部,您可以打印i的值,现在是1

答案 7 :(得分:-2)

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为0因为你没有在printf格式字符串中添加任何空格,所以1彼此相邻。

当i = 1时,然后循环执行i = 1,然后i = 2,然后i = 3,...,然后i = 2147483647(或者INT_MAX是什么),然后换行大约到i = -2147483648,然后i = -2147483647,然后i = -2147483646,并且最终在打印了数十亿个数字后回绕到0。