无法理解这段C的代码片段

时间:2012-11-03 15:03:10

标签: c for-loop int printf short

我的代码是:

#include<stdio.h>

main() {

short int i=0;

for(i<=5 && i>=-1; ++i; i>0)
    printf("%d, ",i);

return 0;
}

输出: -

我不知道从哪里开始,但在序列中结束

..., -4, -3, -2, -1

你可以帮我理解这段代码片段的工作原理吗?

4 个答案:

答案 0 :(得分:2)

for(i<=5 && i>=-1; ++i; i>0)

相当于:

for(; ++i;)

因为i<=5 && i>=-1i > 0表达式没有副作用。

现在控制表达式为++i,这意味着循环执行直到++i被评估为0

ishort个对象,因此++i相当于i = (int) i + 1

(int) i + 1转换为short对象i并且该值无法在short中表示时,转换是实现定义的(请参阅C99,6.3.1.3p3 )。

在您的实现中,行为是当值short中无法表示时,它只是环绕并变为巨大的负值(SHRT_MIN)。循环重复执行,直到++i控制表达式为0

答案 1 :(得分:0)

这是一个格式错误的句子,在句法上是正确的。 它不是有意义的初始化(例如i = 0),而是有一个计算结果为true的语句。作为比较,当i达到零时,它仅增加变量i并结束。每次成功迭代后要执行的结束语句都不执行任何操作。

声明的工作部分等同于while(++ i)printf(“%d”,i); (由于2的补数的性质,它从1,2,3,4,...,32766,32767循环,并包裹到负数 -32768,-32767,...,-3,-2,-1。 (并在下一次迭代时停止,当i == 0时)

编辑:循环可能永远持续,直到满足条件i == 0。计算机中的整数计算通常以模2 ^ 16或模2 ^ 32,模2 ^ 64等计算。只是将16位数中可用65536个不同值的范围映射到2个范围非常方便:0 ... 32767和32768 ... 65535,其中后一部分可以解释为正整数[unsigned]或者为负整数,其值为(x-65536)。 c语言关键字已签名要求计算机执行此操作。

答案 2 :(得分:0)

in

for(i<=5 && i>=-1; ++i; i>0)

i<=5 && i>=-1

表示true,因为0 <= 5 and 0 >= -1

为什么你得到-2,-1? 这是缓冲区溢出。当您向MAX_INT添加1时,您将获得负数

01111

添加1

10000

第一位是负位(1 - 数字是负数,0 - 是正数)

查看http://en.wikipedia.org/wiki/Two%27s_complement

您也可以尝试将int修改为unsigned int


输出

1, 2, 3, 4, 5,
....
-5, -4, -3, -2, -1

您可以通过

进行检查
 program.exe > out.txt

答案 3 :(得分:0)

您的for循环中的子句会混淆,这会导致您一直计入最大的短整数值。当你加1时,它会循环到最小的短整数值,一个负数,然后继续计数直到它变为0,此时循环最终停止。它循环的原因是因为整数通常存储在two's complement中,并且大多数CPU和编译器在溢出时不做任何特殊操作;他们只是不断添加,即使结果没有意义。在二进制补码中,最大整数值表示为0111...;当你加1时,得到1000...,这是最小的负整数。

在C for循环中,表达式为for(initializer; condition; update) body

初始化程序在开头运行一次,以初始化任何变量。由于你只是进行一些比较,它在你的循环中基本上什么都不做。

条件每次迭代运行一次,然后运行该迭代,以测试循环是否应该继续。您的条件++i。这会增加i(向其添加一个)并返回结果。因此,在第一次传递时,i0开始,将其递增到1for循环使用该值来决定循环是否应该继续。除0之外的任何数字在C中都被视为“真”,因此循环继续;蚂蚁它一直持续到i-1为止,因此递增它会留下0,这是一个假值。

update 表达式在主体之后每次迭代运行一次,以更新可能需要继续迭代的任何变量。你只是在这里进行比较,因为它没有使用该值,所以你基本上什么都不做。

最后,你的for循环基本上与:

相同
for (;++i;)
    printf("%d, ",i);

这也与:

相同
while (++i)
    printf("%d, ",i);

你可能的意思是:

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