C ++基础:基于范围的for循环和将C样式数组传递给函数

时间:2016-05-01 23:13:44

标签: c++ arrays parameter-passing ranged-loops

我试图学习C ++,但我不能在这里解决这个代码,尽管花了很多时间寻找答案:

#include <iostream>

void printArray1(int (&array)[3]) {
    for(int x : array)
        std::cout << x << " ";
}

void printArray2(int array[]) { 
    for(int x : array) // compiler error, can't find begin and end
        std::cout << x << " ";
}

int main() {
    int a[3] = {34,12,88};

    for(int x : a)
        std::cout << x << " ";
    std::cout << std::endl;

    printArray1(a);
    printArray2(a);
    std::cout << std::endl;

    return 0;
}

在printArray1中,我们接收的参数是对大小为3的数组的引用。这是否意味着我们正在接收整个数组的地址,或者我们只是接收到大小数组中第一个元素的地址3?此外,该参数如何传递给循环?

在printArray2中,我们正在接收指向数组中第一个元素的指针,对吗?换句话说,我们也收到一个像printArray1一样的地址?因此,此函数中基于范围的for循环将无法编译,因为我们没有数组的大小数据,对吧?

最后,当我们尝试在main中使用基于范围的for循环进行打印时,我们究竟要将哪些内容传递给循环?它是指向数组中第一个元素的指针,如果是这样,如果printArray2中的for循环不接受指针,为什么会编译?

我对C ++的理解还很基础,所以我非常感谢你的帮助,谢谢!

3 个答案:

答案 0 :(得分:3)

基于范围的for循环适用于可与std::beginstd::end一起使用的所有类型。

数组和指针不一样。数组具有固定大小,指针不具有。因此std::beginstd::end适用于数组 - 但不适用于指针。这也解释了为什么基于范围的for循环适用于一个,而不是另一个。

数组也可能衰减到指针。例如,当传递给采用指针参数的函数时,就会发生这种情况。或者,当传递给采用不确定大小的数组参数的函数时(实际上与指针参数相同)。发生这种情况时,尺寸信息会再次丢失。

所以这取决于你如何定义函数。第一个函数采用数组,第二个函数采用指针。这就是为什么第一个保留大小信息和循环工作的原因。

然而,它限制了该功能可以采取的措施。第二个函数可以使用int b[2],而第一个函数则不能。

答案 1 :(得分:0)

[3]的情况下,函数知道数组的类型有多大。引用通常被实现为指向引用的东西的指针,但是在C ++中,很长的时间都是为了留下实现细节(有时可以实现优化)。对于其他地方的数据,引用是别名,与指针(类似于邮政地址)略有不同。当编译器具有长度时,迭代很容易,而C ++做正确的事。

[]案例中,这是C样式语法。它不是参考。它与int * array相同。数组的大小既不是tue编译时类型(在函数内)的一部分,也不是运行时状态(它是单个int指针)的一部分。显然,如果没有长度,迭代是不可能的。

答案 2 :(得分:0)

根据关于arraysRanged-based for loop

的cppreference

printArray1 中,数组参数是 int references 的数组,每个参数都会引用数组的前3个值。作为一个论点传递。

printArray2 中,数组参数是一个指针,指向作为参数传递的数组的第一个值。有了它,您可以访问该数组的所有值。

最后,它不是指针,而只是 a 数组的引用。 在该特定情况下,重要的是要知道,对于每次迭代,将对 x 变量执行迭代值的副本。 如果您想阻止所有这些副本发生,您应该声明一个引用。

示例:

for(int &x : a)
    std::cout << x << " ";
不过,你还应该看看array container,它是现代风格的数组。