【问题标题】:What is the accurate description of the use in "when use an array"“当使用数组时”中使用的准确描述是什么
【发布时间】:2018-07-22 18:12:30
【问题描述】:

当我们使用数组时,它会自动转换为指向它的指针 第一个元素。 (C++ 入门第 5 版。pp129)

int ia[3][4];

for (auto p = ia; p!= ia + 3; ++pp){
  for (auto q = *p; q ! = *p + 4; ++q)
     cout << *q << ' ';
  cout << endl;
}

上面的代码 sn-p 就是引用的一个很好的例子。 p是一个指针指向一个由四个整数组成的数组q是一个指针指向一个整数

然而,基于范围的循环有不同的故事

for (auto row: ia) // the code won't compile in fact 
  for (auto col: row) 

这里,row 的类型是指针指向 int(因为第二个循环不会编译)。这是为什么?这不是 use 数组的情况吗?

【问题讨论】:

  • 已经使用std::arraystd::vector 了。
  • imho pp.129 不是应该在名为“c++ 入门”的书中讨论原始数组的地方,可能在附录 XVI 中:P
  • @MichaelNastenko -- 指针指向具有类型的对象。该类型可以是“四个 int 的数组”。这正是示例代码中的pia 是 3 个 4 个整数的数组;它的名称衰减为指向其第一个元素的指针,这是 3 个 4 个整数数组中的第一个,即 4 个整数数组。
  • @MichaelNastenko -- 完全正确是真的。 ia[0] 的类型是四个 int 的数组。在许多情况下,名称衰减为指向其第一个元素的指针,但这是如何使用的结果;这不会影响其类型。这种衰减发生在很多情况下,程序员往往会忘记它的存在,但如果你忽视它,你迟早会被咬伤。要查看差异,请编写一个简单的程序,显示sizeof(ia[0]sizeof(int)

标签: c++ arrays loops pointers


【解决方案1】:

“使用数组”是一个非常随意的表达方式。

要了解如何使用数组,首先必须了解基于范围的 for 循环的作用。让我们扩展您的外部循环以使用等效的常规 for 循环(我已经简化了一点):

{
    for (auto __begin = std::begin(ia), __end = std::end(ia);
            __begin != __end; ++__begin) {
        auto row = *__begin;

        for (auto col: row); // oops. Cannot use range-for with a pointer
    }
}

这里的问题是,auto row 的推断类型是什么?

*__begin 的结果是“4 个整数数组”类型的左值。 auto 遵循模板参数推导规则。参数不能是数组对象,所以auto 永远不能被推断为数组。在这种情况下,数组类型衰减为指向第一个元素的指针,即指向 int 的指针。

一个参数可以推断为“对 4 个整数数组的引用”,所以这会起作用:

for (auto& row: ia)
    for (auto col: row) 

【讨论】:

    【解决方案2】:

    您的问题是for (auto row: ia) 导致ia 的元素衰减为指针,因此row 成为指针类型。这意味着您不能使用for (auto col: row),因为没有为指针定义开始函数。

    您需要做的是获取一个引用,以便您引用一维数组并且没有指向它的指针。看起来像

    for (auto& row: ia) // reference to each row in the array
        for (auto col: row) // copy of each element in the row
    

    【讨论】:

    • 但是为什么不是“衰减”到指向数组的指针而不是指向数组第一个元素的指针(这里是int)
    • @SLN 因为在ia 上调用的std::begin 返回一维数组,因为二维数组的每个元素都是一维数组。该一维数组(int[4])衰减为int*,这使得row成为int*
    猜你喜欢
    • 2011-07-19
    • 2020-01-12
    • 1970-01-01
    • 2015-03-23
    • 2010-09-22
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 2020-12-09
    相关资源
    最近更新 更多