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

本文关键字:循环 C++ | 更新日期: 2023-09-27 17:58:53

我刚刚编写了一个简单的反向循环,如下所示:

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

但它并没有像预期的那样停在 0 处,而是远远下降到负值,为什么?
请参阅此 ideone 示例:http://ideone.com/kkixx8

(我在 c# 和 c++ 中测试了它(

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

您将 int 声明为无符号。 它将始终为>= 0。 看到负值的唯一原因是 printf 调用将其解释为有符号 (%d( 而不是无符号 (%ud(。

尽管您没有要求解决方案,但以下是解决问题的两种常用方法:

// 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);

无符号的 int 永远不会变成负数。

在 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。它只是环绕着。您看到负值是因为您格式化输出的方式(将其解释为有符号的 int(。

i小于零时循环中断。但i是无符号的,并且永远不会小于零。

在你的

for 循环中

for (无符号整数 i = 50; i>= 0; i--( printf("i = %d'", i(;

i的值减少 1,当您的值 i==0 然后循环递减时,尝试分配 i--意味着i=-1

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