范围for遍历数组 | 青训营 ;

36 阅读1分钟

那么事情是这样的

来自c++primer 习题3.43

int ia[3][4]={ {0,1,2,3}, {4,5,6,7}, {8,9,10,11}, };

#include
using namespace std; int main() { int ia[3][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, }; for (auto a : ia) { for (auto b : a) cout << b; } }

你很容易写出这样的代码 然而这串代码甚至无法通过编译

为什么???

我们使用typeid 来验证下a

#include #include
using namespace std; int main() { int ia[3][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, }; for (auto a : ia) { cout<<typeid(a).name()<<endl; } for (auto &a : ia) { cout << typeid(a).name() << endl; } }

可以看到

auto a a对应int*

auto&a a对于int[4]

auto不好好工作么?

一个&会产生这样的变化 why??? c++primer给出了答案

那么让我们返回题目 使用范围for 但不使用类型别名,auto,decltype 进行编程

这太简单了 auto&a 换为 int a[4]就行了呗

恭喜你 你创建了一个数组! 哦 你甚至没有成功创建 因为你没给他初始化(编译器这样告诉你)、

聪明的你想到 既然auto不行 auto&可以 那么是不是int &a[4]是可行的

等等 你是不是忘了“数组不能引用”

编译器提醒你“ 引用数组是非法的!!!!”

到底该怎么写。。。。 被auto惯坏的你陷入了沉思

我们看下面的代码

#include #include
using namespace std; int main() { int ia[3][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, }; for (int (&a)[4] : ia) { cout<<typeid(a).name()<<endl; } for (auto &a : ia) { cout << typeid(a).name() << endl; } }

仅仅是在&a外加上了神奇的 ()居然成功了耶( •̀ ω •́ )y a的类型正确了

这其实像是 指针数组 与数组指针 int *a[] int(*a)[]

int main() { int ia[3][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, }; int (&a)[4] = ia[0]; for (auto p : ia[0]) cout << p << endl; a[0] = 123;a[1] = 234;a[2] = 345;a[3] = 456; for (auto p : ia[0]) cout << p <<endl;

};

我们可以看到 数组的值确实被改变了 那么a不就是数组引用么

a是一个引用 但不是数组的引用

事实上数组不能引用指的是数组的元素不能是引用

int &a[4] 实际上是创建了一个 有四个元素 元素类型是int& 的数组a

那么事情就这样完美收场啦