C++Primer_范围for处理多维数组

在学习多维数组时,我想把我所创建的多维数组,以及对数组的操作结果,标准输出出来,验证代码是否正确。
用for循环有两种方法:

  1. 传统的for循环,可以索引下标或对迭代器进行操作
  2. 范围for循环
constexpr size_t rowCnt = 3, colCnt = 4;   //三行四列的容量
int iarr[rowCnt][colCnt];                  //默认初始值为0的二维数组 
for (size_t j = 0; j != rowCnt; ++j) {
    for (size_t k = 0; k != colCnt; ++k) {
        iarr[j][k] = j*colCnt + k;         //对数组元素进行操作
    }
}

数组改变后,需要标准输出。我先尝试了for循环索引下标的方法:

for (size_t i = 0; i!= rowCnt;++i){
    for (size_t j=0;j!=colCnt;++j){
        cout << iarr[i][j] << " ";
    cout << endl;
    }
}

接着我尝试了 范围for循环的方法:

for (auto row:iarr){
    for (auto item:&row){
        cout << item <<  " ";
    }
    cout << endl;
}

看似正确,但却没那么简单。代码出错了。
经过一番研究,找到了问题所在,修改后的代码如下:

for (auto &row : iarr) {     
    for (auto &item : row) {
        cout << item << "  ";
    }
    cout << endl;
}

将row和item都修改成引用类型。由前面的学习可值,引用类型可直接修改引用对象的值,那么和数组又是什么关系呢?

引用类型修改元素的值,代码如下:

//引用类型修改数组的元素
size_t cnt = 0;
for (auto &row : iarr) {
    for (auto item : row) {
        item = cnt;        //对item赋值,就是对元素进行赋值
        ++cnt;
    }
}

下面分析原因:

//数组作为auto语句变量初始值                   代码3
int ia_test[] = { 0,1,2,3,4,5 };
auto ia2_test(ia_test);         //ia2_test是一个指针,指向ia_test的首元素
//尝试对ia2_test赋值
ia2_test = 5;                   //错误:无法从int转换为 int*
auto ia2_test = ia_test[0];     //实际上编译器所执行的语句
//decltype能够避免数组转换为指针                 代码4
int ival_t = 5;
int *p_t = &ival_t;   //p是一个整型指针
decltype(ia_test) ia3_test = { 0,1,2,3,4,5 };
ia3_test = p_t;     //错误
ia3_test[4] = 42;   //正确:说明ia3_test是一个数组
  • 浅层:使用引用类型在循环中进行写操作
  • 深层:外层循环声明成引用类型,是为了避免数组被自动转化成指针,初始化row时得到指向iarr首元素的指针,内层循环将试图在一个 int*内进行遍历
    • 当数组作为一个auto变量的初始值时,推断得到的类型是指针而非数组(代码3)
      • 补充:
        • 大多数情况下,数组名其实是指向数组首元素的指针
        • 当使用decltype时,不会发生上述的转换(代码4)

总结:

  • 要使用范围for语句处理多维数组,除了最内层的循环外,其他所有的循环控制变量都应该是引用类型。

「C++Primer 5th」3.6 多维数组 P114


排版上有待进步。

ask:2017/03/15;sloved:2017/03/15;commit:2017/03/26

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值