C#和C++中反向循环的奇怪行为

5
我刚编写了一个简单的反向循环,如下所示:
for (unsigned int i = 50; i >= 0; i--)
    printf("i = %d\n", i);

但它没有停留在0,而是下降到负值,为什么?
请参考这个 ideone 示例:http://ideone.com/kkixx8

(我在C#和C++中进行了测试)

6个回答

13

你将int类型声明为无符号(unsigned),这意味着它始终会大于等于0。出现负值的唯一原因是你的printf函数调用将其解释为有符号数(%d)而非无符号数(%ud)。


但是 printf 输出了一个负值。 - bricklore
@MalteSchmitz 不是在C#中。 - Sriram Sakthivel

3

虽然您没有要求解决方案,但以下是两种常见的解决该问题的方法:

// 1. The goes-to operator
for (unsigned int i = 51; i --> 0; )
    printf("i = %d\n", i);

// 2. Waiting for overflow
for (unsigned int i = 50; i <= 50; i--)
    printf("i = %d\n", i);

不错的解决方案 :) 它们看起来有点像邪恶的黑客。 - bricklore
为了提高可读性,我建议将 i --> 0 改为 i-- > 0。这有点像写 a------b,虽然它可以工作,但意图不明确((a--) - (- (--b)))。 - Caramiriel
@Caramiriel a------b 实际上被解析为 (((a--)--)--)b,这是没有意义的。 - fredoverflow

2

在C#中,这段代码

for (uint i = 50; i >= 0; i--)
    Console.WriteLine(i);

产生以下输出:
50
...
7
6
5
4
3
2
1
0
4294967295
4294967294
4294967293
...

您正在使用一个unsigned int,它永远不可能小于0,因为它会自动循环。您看到负数是因为您以有符号整数的方式格式化输出。


2

无符号整数永远不可能变成负数。


但是 printf 输出了一个负值。 - bricklore
@MalteSchmitz 这是因为您正在使用%d,它适用于整数,而%u适用于无符号整数。 - PomfCaster

2

i小于零时,循环会终止。但是i是无符号的,它永远不会小于零。


printf将i从无符号整数转换为有符号整数,并显示有符号数。 - Stas BZ
printf提供了%d,因此它打印了有符号整数。 - Balu

0

在你的for循环中

for (unsigned int i = 50; i >= 0; i--) printf("i = %d\n", i);

i的值减1,当i==0时,循环减量尝试分配i--,意味着i=-1

等号右侧的-1设置为有符号整数(可能是32位大小),并且将具有十六进制值0xFFFFFFF4。编译器生成代码将此有符号整数移动到您的无符号整数i中,该无符号整数也是32位实体。编译器假定您只有一个正值在等号右侧,因此它只是将所有32位移动到i中。i现在具有值0xFFFFFFF4,如果解释为正数,则为4294967284。但是,%d的printf格式表示应将32位解释为有符号整数,因此您会得到-1。如果使用了%u,则会打印为4294967284。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接