C++中有关数组的一些细节问题

今天读C++ primer发现其中讲数组的一章,有一些东西自己还不是很清楚,所以专门下一篇博客来总结一下数组里面的一些容易忘记的知识。
1. 首先看下面声明数组的几种方式有什么区别:

int *ptr[10];
int &refs[10] = /* */; error
int (*Parray)[10] = &array;
int (&arrRef)[10] = arr;

首先,第一个的意思是定义了一个指针数组,即ptr中存放了是个int*类型的指针值。
第二个是一种错误的写法,因为没有存放引用的数组,所以是错误的。
第三个虽然和第一个相比,就多了个括号,但含义差别还是很大的,它的意思是指Parray是一个指针类型,它指向的是一个存放有10个int类型数据的数组。
而第四个和第三个类似,不过这里arrRef是一个存放有10个int型数据的引用。

  1. 再来看一下二位数组的一些知识:
    首先是二维数组的初始化,这里有两种方式,如下:
int ia[3][4] = {
    {0, 1, 2, 3},
    {4, 5, 6, 7},
    {8, 9 ,10 , 11}
};

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

然后看一下二维数组的遍历方式,首先是最常用的遍历方式:

constexpr size_t rowCnt = 3, colCnt = 4;
int ia[rowCnt][colCnt];
for(size_t i = 0; i != rowCnt; ++i)
{
    for(size_t j = 0; j != colCnt; ++j)
    {
        ia[i][j] = i * colCnt + j;
    }
}

下面我们用C++11中新添加的特性Range-For来遍历:

size_t cnt = 0;
for(auto  &row : ia)
{
    for(auto &col : row)
    {
        col = cnt;
        ++cnt;
    }
}

注意,因为我们要修改数组ia里的值,所以在遍历的时候用的是引用的类型,当然如果不需要修改里面的值,只是对值进行输出的话,该怎么写呢?首先看一下下面这种写法:

for(auto row : ia)
{
    for(auto col : row)
    {
        cout << col << endl;
    }
}

以上写法看起来好像没问题,但其实是通不过编译的,这是因为数组和指针之间转换的问题。C++中在很多情况下,数组都会被看做成一个指针,如上面这种方式,row其实是ia中的一个行数组,所以row会被转换成一个int*类型的指针,导致了内层循环col : row出现错误。所以为了便面row被当作一个指针,我们需要用引用的方式,如下:

for(const auto &row : ia)
{
    for(auto col : row)
    {
        cout << col << endl;
    }
}

下面我们再来看一下用指针的方式如何来遍历二位数组:

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

上面这种方式的关键在于理解p和q的类型,首先p的类型是int (*p)[4]的,及p是一个指向存放4个int数据的数组的指针。而*p就是一个4大小的int型数组,所以q就是这个数组的指针。简单来说,p和q都是一个指针,但这两个指针确实不同的,p++每次指针前进的距离是sizeof(int) 4, 而q就是一个int*类型的,q++每次前进的距离是sizeof(int)。

利用begin和and函数,我们可以更简单地来遍历一个二维数组:

for (auto p = begin(ia); p != end(ia); ++p)
{
    for(auto q = begin(*p); q != end(*p); ++q)
    {
        cout << *q << ' ';
        cout << endl;
    }
}

上面都用到了C++11中的auto关键字,当然也会可以明确指明类型的,如下:

using int_array = int[4];
typedef int int_array[4];
for(int_array *p = ia; q != ia + 3; ++p)
{
    for(int *q = *p; q != *p + 4; ++q)
    {
        cout << * q << ' ';
        cout << endl; 
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值