我不明白这个程序是如何工作的

时间:2013-02-28 14:23:09

标签: c

在以下程序中

#include<stdio.h>   
int main()    
{    
    char i=0;    
    for(i<=5 && i>=-1;++i;i>0)   
        printf("%d\t",i);
    return 0;    
}    

'我'从1到127打印,然后从-128打印到-1。

为什么会这样?

7 个答案:

答案 0 :(得分:14)

这一直是我生命中见过的最糟糕的循环。 For循环的格式如下

for ( initalization; condition; update )

for循环的开头,initialization发生。这通常类似于i = 0。在每个循环的顶部,评估condition(通常类似于i < 5)以查看循环是否应该继续,如果循环继续,则执行update(同样,通常类似于++i),循环再次执行。

这里发生了什么,循环是使用++i作为条件,因此它只会在++i评估为0值时终止,因此您从{{1}开始}并递增,直到1char i溢出到128,然后继续递增,直到达到-127,此时-1计算为{{1}并且循环终止

修改

所以根据你的代码,++i是在循环的第一次迭代开始时执行的(这完全没有任何结果),然后0被评估为布尔状态(i<=5 && i>=-1 1}}开始,并使用预增量,评估为++i,因此,不是0所以布尔值通过),然后是1 0部分执行,再一次,什么都不做。

<强> EDIT2

如果你的问题真正归结为update,那么约阿希姆对这种行为提供了很好的解释

答案 1 :(得分:3)

好消息:在您的实施中,char已签名!

此外,发生的情况是i的值从127溢出到-128,因为127是符合签名char的最大正值。

编辑:实际上,我不确定char在您的实施中的签名情况,但循环完全被破坏了:

应该是

for (i = 0; i <= 5; i++)

但这只是猜测。这很难解释。

答案 2 :(得分:2)

char是编译器中带符号的8位整数。它可以表示-128到+127的值。循环结束条件为++i,并且在C中,所有非零值都被认为是真的,因此它将循环直到++i为零,这将在i为{{1}时发生}}

如果从127到-128的原因是因为签名整数在计算机中的工作方式。 127的二进制位为-1,-128的位模式为01111111。向1000000添加一个将导致01111111

总而言之,你的10000000循环没有任何意义。它在语法上是正确的,但没有任何意义。有关for循环如何工作的解释,请参阅Dan F的答案。

答案 3 :(得分:2)

答案 4 :(得分:1)

程序将打印时的“i”解释为8位有符号整数,表示符号为1位,数据为7位。这为有效值提供了-128到127的范围。

在printf之前的“for”循环 preincrements i,因此给它一个第一遍值1,并且增量继续,直到i + 1 = 128 - 它翻转了一个符号位有符号整数,然后运行循环,直到++ i导致i为0。

答案 5 :(得分:1)

顺便说一下,for循环是可怕的。你知道它应该是for(intialisation; end condition; increment),对吧?

反正。我被初始化为0; for循环的第一个循环是测试具有预增量的结束条件(++ i)。所以我增加到1,循环运行打印1。

现在重复一遍。每个循环为i打印一个更高的值,因为结束条件测试是预先递增i。

最终我达到了127;然后它增加到128,但是你将它打印为期望有符号整数的“%d”,因此使用二进制补码将其解释为-128。

然后增量一直持续到255(打印为-1)。下一个预增量会导致溢出,所以我再次变为0,此时“结束条件测试”的计算结果为假,循环停止。

答案 6 :(得分:1)

这个程序用于循环非常奇怪。 你通过检查它们“i&lt; = 5&amp;&amp; i&gt; = - 1”来初始化你的循环变量 - 没有完成任务。 在循环期间,你评估条件“++ i”,这是真的,直到i = -1;在增量步骤中,您只需检查数字是否大于零。

你实际上是这样做的:

for(i = 1; i != 0; i++)
{
    printf("%d\t",i);
}

溢出超过127时,您会得到1到127之间的数字,以及-128到-1之间的数字。