我试图学习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 ++的理解还很基础,所以我非常感谢你的帮助,谢谢!
答案 0 :(得分:3)
基于范围的for循环适用于可与std::begin
和std::end
一起使用的所有类型。
数组和指针不一样。数组具有固定大小,指针不具有。因此std::begin
和std::end
适用于数组 - 但不适用于指针。这也解释了为什么基于范围的for循环适用于一个,而不是另一个。
数组也可能衰减到指针。例如,当传递给采用指针参数的函数时,就会发生这种情况。或者,当传递给采用不确定大小的数组参数的函数时(实际上与指针参数相同)。发生这种情况时,尺寸信息会再次丢失。
所以这取决于你如何定义函数。第一个函数采用数组,第二个函数采用指针。这就是为什么第一个保留大小信息和循环工作的原因。
然而,它限制了该功能可以采取的措施。第二个函数可以使用int b[2]
,而第一个函数则不能。
答案 1 :(得分:0)
在[3]
的情况下,函数知道数组的类型有多大。引用通常被实现为指向引用的东西的指针,但是在C ++中,很长的时间都是为了留下实现细节(有时可以实现优化)。对于其他地方的数据,引用是别名,与指针(类似于邮政地址)略有不同。当编译器具有长度时,迭代很容易,而C ++做正确的事。
在[]
案例中,这是C样式语法。它不是参考。它与int * array
相同。数组的大小既不是tue编译时类型(在函数内)的一部分,也不是运行时状态(它是单个int指针)的一部分。显然,如果没有长度,迭代是不可能的。
答案 2 :(得分:0)
根据关于arrays和Ranged-based for loop
的cppreference在 printArray1 中,数组参数是 int references 的数组,每个参数都会引用数组的前3个值。作为一个论点传递。
在 printArray2 中,数组参数是一个指针,指向作为参数传递的数组的第一个值。有了它,您可以访问该数组的所有值。
最后,它不是指针,而只是 a 数组的引用。 在该特定情况下,重要的是要知道,对于每次迭代,将对 x 变量执行迭代值的副本。 如果您想阻止所有这些副本发生,您应该声明一个引用。
示例:
for(int &x : a)
std::cout << x << " ";
不过,你还应该看看array container,它是现代风格的数组。