0

我发现了一个非常奇怪的 c++ 代码。有人可以为我解释 for 循环条件吗?
为什么它只有一个数组和索引变量?

include <iostream>

using namespace std;

int main()
{
   int a[] = {1, 2, 3, 4, 5};

   for (int i = 0; a[i];i++){
      cout << a[i] << endl;
   }

  return 0;
}

结果是:

1

2

3

4

5

-858993460

2424376

12655176

1

3492888

3483368

1402216725

为什么它输出 12 个元素?那些额外的 7 个元素来自哪里?非常感谢!

4

6 回答 6

7

在 C/C++ 中,可以用数字代替布尔条件。发生这种情况时,false当数字为零时考虑结果;否则,视为true

现在您可以很容易地看到循环有一个无效的终止条件:它希望在数组中找到第一个零时停止,但数组没有零,因此循环继续超出数组边界。在您的情况下,它在七次额外迭代后发现零,产生垃圾值(它可能已经崩溃,因为它是未定义的行为)。

将数组初始值设定项更改为包含零可以解决问题:

int a[] = {1, 2, 3, 4, 5, 0};

当然,迭代到数组中的元素数量也可以。

于 2013-06-17T19:49:36.170 回答
4

表达方式

a[i]

is 相当于

a[i] != 0

在期望条件的上下文中。所以循环迭代直到它在数组中找到一个为零的元素。由于数组的键中没有元素满足此条件,因此代码会越界读取数组,因此您的程序会调用未定义的行为(并在请求的内存位置打印值,这似乎是垃圾)。

于 2013-06-17T19:49:21.190 回答
3

该代码具有未定义的行为,因此任何事情都可能发生。该数组有 5 个元素,因此允许取消引用的最后一个索引是 4。一旦您使用 arr[5] 的值,您的程序就会毫无希望地出轨。

(在这个特定的运行中,它可能在第 13 个插槽处发现了一个看起来为 0 的垃圾,因此停在那里,但如前所述,如果您根本看不到任何输出或已邮寄给您的老板,那也没关系)。

于 2013-06-17T19:48:39.010 回答
1

它是一种未定义的行为。在您的情况下,循环终止条件是a[i] !=0在跨越数组边界后的 12 个元素之后发生的。

于 2013-06-17T19:50:44.077 回答
1

您访问超出数组长度,因此在程序将超过 5 个成员写入输出(其中 i > 4 )后您无法预测该值,这就是您编程导致未定义行为的原因。程序将一直运行,直到它意外遇到 a[i] 等于 0 的 i 值。

你可以像这样修复代码

unsigned length = sizeof(a) / sizeof(a[0]);
for (int i = 0; i < length ;i++){
      cout << a[i] << endl;
}
于 2013-06-17T19:54:16.820 回答
0

循环停止的条件是a[I],等于a[I]为零。所以实际上你已经超出了数组的边界并输出了一些脏数据。

于 2013-06-17T20:02:32.703 回答