在以下程序中
#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。
为什么会这样?
答案 0 :(得分:14)
这一直是我生命中见过的最糟糕的循环。 For循环的格式如下
for ( initalization; condition; update )
在for
循环的开头,initialization
发生。这通常类似于i = 0
。在每个循环的顶部,评估condition
(通常类似于i < 5
)以查看循环是否应该继续,如果循环继续,则执行update
(同样,通常类似于++i
),循环再次执行。
这里发生了什么,循环是使用++i
作为条件,因此它只会在++i
评估为0
值时终止,因此您从{{1}开始}并递增,直到1
从char 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之间的数字。