转载

由二维数组遍历而引发的数组与指针的问题

今天在阅读《c++ primer fifth edition》中多维数组一节时,写一段遍历二维数组中元素的程序时,对于以前关于数组与指针的一些模糊点有了一些较为清晰的理解,将其记录下来,程序很简单,就是遍历输出二维数组中的元素:

1.以前对二维数组的遍历,本人全部都是定义i,j两个变量,一个控制外层,一个控制内层:

 
 1 for(int i = 0; i < 3; i++) 2     { 3         for(int j = 0; j < 4; j++) 4             cout << a[i][j] << " "; 5         cout << endl; 6     } 
2.c++中二维数组,其实是一维数组,只是其中的每个元素又是一个数组,因此我们可以这样写:

 1 for(int (*i)[4] = a; i != a + 3; i++)   //i是指向数组的指针,数组中含有4个整型变量 2     { 3         for(int *j = *i; j != *i + 4; j++)  //*i得到的是指向数组中首元素的指针! 4             cout << *j << " "; 5         cout << endl; 6     } 

由二维数组遍历而引发的数组与指针的问题

注意 int (*i)[4]表示指向含有四个整型元素的数组的指针,从内层向外层去读,首先是一个指针

int* i[4] 表示含有四个整型指针的数组,从右向左去读

问题所在

起初对于 int *j = *i;不能理解,以为i是指向数组的指针,当然指向数组中的首元素,而解引用*i显然应该是数组中的首元素了,那怎么又赋值给一个指针了呢?

从网上查了一些资料才发现, *i原来也表示指向数组首元素的指针。

进行了一些测试,测试程序如下:

 1 int ia[2][3] = {{1,2,3}, {4,5,6}}; 2     int (*pia)[3] = ia; 3     cout << "pia = " << pia << endl;            //指向数组的指针 4     cout << "*pia = " << *pia << endl;          //对指向数组的指针解引用得到指向数组中首元素的指针 5     cout << "pia + 1 = " << pia + 1 << endl; 6     cout << "*pia + 1 = " << *pia + 1 << endl; 

结果如下:

由二维数组遍历而引发的数组与指针的问题

显然pia 和 *pia的输出正是上面说的情况,而对于pia+1和*pia+1就容易理解了,pia是指向数组的指针, 可以将其“1个单位”(也就是+1)理解成整个指向的数组大小 ,而*pia相当于“进入到了指向的数组内”, 其“1个单位”显然应该是数组中一个元素。

3.通过范围for(range for)遍历二维数组

  1     for(const int (&i)[4] : a)  2     {  3         for(int ii: i)  4             cout << ii << " ";  5         cout << endl;  6     }  7     cout << "------------------------------" << endl;  8   9     for(const auto & i : a) 10     { 11         for(auto ii : i) 12             cout << ii << " "; 13         cout << endl; 14     } 

范围for是c++11新增加的遍历整个序列的一种简单手段,可以实现对下标的自动管理,无需程序员手动管理,由此看来对于遍历整个序列可以,而需要遍历部分序列就不方便了,毕竟下标的管理是不透明的

需要说明的一点是,在外层遍历中,每个元素的类型是引用,而非普通指针类型,因为如果是指针类型的话,在内层循环的时候,遍历的序列就成了指针了,是不行的,而将元素声明称数组的引用类型则可。

4.使用类型别名来简化

 
 1 using int_array = int[4]; 2     for(int_array  *i = a; i != a+3; ++i) 3     { 4         for(int *j = *i; j != *i + 4; ++j) 5             cout << *j << " "; 6         cout << endl; 7     } 
       由二维数组遍历而引发的数组与指针的问题

后面三种方法,其实都是相同的原理,都是利用了二维数组是“由数组组成的数组”这一规则,关键是一些细节上的理解,尤其是涉及到了指针,更是需要小心翼翼。

同时,反思自己,今后遇到模棱两可的问题,千万不能放过,一定要多多查询资料, 至能够说服自己

一些错误之处,请各位指出,虚心学习。

正文到此结束
Loading...