【问题标题】:C++ : auto variable deduction differs range for loop vs a normal for loop for multi dimensional arrayC++:自动变量推导不同的循环范围与多维数组的正常循环
【发布时间】:2017-09-06 22:53:44
【问题描述】:

以下是:

int ia [3][4] =  {
                        {0, 1, 2, 3},
                        {4, 5, 6, 7},
                        {8, 9, 10, 11}
                     };
  1. 正常分配:

    auto p = ia;
    

    这是可以理解的。
    数组 ia 返回指向其第一个元素的指针,该元素是 4 个元素的第一行(4 个元素的批次)。
    p 有 int (*)[4]。执行 p + 1 将指向下一批 4 个元素。

  2. 使用范围:

    for (auto row : ia) {
            for (auto col: row)
                    cout << col << " ";
            cout << endl;
    }
    

    为什么 row 不是 int (*)[4],因为每个循环都像前面的示例一样返回 4 个元素的批次?
    相反,它是 int *.
    当我将鼠标悬停在 row 变量上时,它给了我 int *..

谢谢

【问题讨论】:

  • 你是如何得出int*的结论的?因为我无法重现这样的推论。
  • 什么是arr1
  • @StoryTeller 它被const auto 腐烂了。
  • 第一个不是正常的for循环。 正常 for 循环将是:for (int row = 0; row &lt; 3; ++row){ for (int column = 0; column &lt; 4; ++column) { cout &lt;&lt; ia[row][column] &lt;&lt; "\n";} }
  • @ThomasMatthews:不,这是一个相当不错的“正常” for 循环,基本上用迭代器表示。

标签: c++ c++11


【解决方案1】:

基于范围的for 循环获取每个数组元素,并在每个循环轮次中从给定初始化程序派生的声明或表达式中使用它。数组元素的类型为 int[4],因此对于表示当前范围元素的发明变量 int __elem[4],您的循环体有效地表示:

const auto row = __elem;   // __elem is int[4]

现在看起来应该很熟悉:右边的数组表达式衰减为指向其第一个元素的指针,因此类型为int

如果你想避免衰减,你需要绑定一个reference来代替:

const auto& row = __elem;    // row is int(&)[4]

把它放回到你的基于范围的循环中,你想要:

for (const auto& row : ia) {
    for (const int& cell : row) {
        // ...
    }
}

【讨论】:

  • 为什么会腐烂?如果没有衰变,它将是 int (*)[4] .. 很抱歉对 c++ 不熟悉 .. 什么是衰变?
  • @yapkm01:在许多情况下,数组类型的值(左值或右值)变成指针元素类型的纯右值,其值是第一个数组元素的地址。这被称为“衰变”。它非常基础,因为它支持下标等基本功能:给定int a[3],我们可以说a[i],相当于*(a + i),而这里a 衰减为&amp;a[0],因此指针算法适用于数组元素。如果没有衰减,a + i 的表达式将毫无意义。 Decay 还允许我们编写 for (auto* it = a; it != a + 3; ++it) use(*it); 来迭代数组。
  • 如果你把 auto row= ia;或 const auto row = ia;并将鼠标悬停在变量行.. 你会看到它是 int (*)[4]。为什么使用范围 for 循环会有所不同?
  • @yapkm01:这与我刚才所说的完全一致。 iaT 的数组,它衰减为 T*。 (您只需要填写T = int[4]。)您可能在这里太深了;先尝试更简单的类型,直到你完全理解数组的概念。数组数组的工作方式相同,但更容易迷失在复杂性中。
  • @yapkm01:让我们再试一次:T a[7]; auto it = a; 现在itT*,其值为&amp;a[0],对吗?到现在为止还挺好。现在做同样的事情,但将T 替换为int[13]int b[7][13]; auto it = b;。同样it 是指向第一个元素&amp;b[0] 的衰减指针。 b[0] 是一个int[13],所以它的地址类型为int(*)[13]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-30
相关资源
最近更新 更多