【问题标题】:A C++ for loop on an array数组上的 C++ for 循环
【发布时间】:2013-06-13 21:07:01
【问题描述】:

我发现了一个非常奇怪的 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 个元素来自哪里? 非常感谢!

【问题讨论】:

  • 因为未定义的行为。

标签: c++ arrays for-loop indexing conditional-statements


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

    表达式

    a[i]
    

    是等价于

    a[i] != 0
    

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          您访问超出数组长度,因此在程序将超过 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;
          }
          

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2022-06-15
              • 1970-01-01
              • 1970-01-01
              • 2016-05-05
              • 1970-01-01
              • 2017-03-07
              • 2020-02-29
              • 2018-12-03
              相关资源
              最近更新 更多