指针和二维数组
首先定义一个数组:
1 int a[5][3] = { {1,6,11}, 2 {2,7,12}, 3 { 3,8,13 }, 4 { 4,9,14 }, 5 { 5,10,15 } 6 };
随便定义的一个二维数组i = 5, j = 3
然后看下面3种方式:
1 int *b = a[0]; 2 int *c = *a; 3 int &d = **a;
其实上面的三种方式的效果是一样的,大牛一看就知道,这不是废话么。我们还是输出下
1 //value 2 std::cout << *b << endl; 3 std::cout << *c << endl; 4 std::cout << d << endl; 5 std::cout << *a[0] << endl; 6 std::cout << a[0][0] << endl; 7 //address 8 std::cout << b << endl; 9 std::cout << c << endl; 10 std::cout << &d << endl; 11 std::cout << &a[0] << endl; 12 std::cout << &a[0][0] << endl;
输出如下:
这里a[0],a,*a,&a[0][0]存放的地址如下图可以看出来
虽然值是一样的,但是类型不一样,同时所表示的含义也是不一样的
a[0] 存放的是第一行的首元素地址,*a 同样。
&a[0][0]存放的是着整个数组的首元素的地址。
a 则是存放着整个数组的首元素地址。
但是这里需要注意的是 a[5][3] 不等于 int **,而是等于(*)[3]。
其实很容易记混淆,我也是老忘记,记得以前面试的时候老会遇到这样的考数组和指针关系的。
<c++实践之路>中有一句话:不要在可以使用索引的地方使用指针。
那么也就是说了解这些关系一点用就没有么?不是,虽然数组名不等于指针,但是,理清这些关系,对把数组作为参数传递的时候,有很大帮助。(以后写关于数组当函数参数的随笔)
接下来,我们来看指针实现下标索引的方法:
先看这个,如果我们这样定义:int *b = a[0]; //定义一个指针b指向数组a第一行的首元素地址
那么,如果我们要找到a[0][2]的地址应该如何表示呢?那就是,b + 2,那么值就是*(b + 2);
那么,如果我们要找到a[1][0]的地址呢?那就是,b + 3 * 1 + 0,那么值就是*(b + 3 *1 + 0 ),为什么要这样写呢,等下解释
同样如果是a[2][3]?那就是,b + 3 * 2 + 3 ,这下看出规律了吧。 对于数组a[][n],如果定义 int *b = a[0],那么对于a[i][j] ,用b来表示 就是 b + n * i + j
因为数组的地址是连续的,比如a数组首元素的起始地址也就a[0][0]的地址是10CF9E4(十进制为 17627620),那么a[1][0]的地址 17627620 + sizeof(int)*3,也就是10CF9F0(十进制为 17627632)
对于int *c = *a; 同样可以得出。
如果要用a来表示a[2][3]的地址呢,由上面很容易就知道是*a + 2 * 3 + 3。
在面试的时候,自己被问道了很多基础的东西,我每每都是说自己记忆力不好,记不住来搪塞,可是,自己仔细想想,很多东西只是自己没有去了解。之前的遇到问题的思路都是: 遇到问题——百度谷歌——查找相关问题——找出适合自己的问题的解决方法——解决。
然而,这样对自己的提升真的不大,就长远发展来看,属于自己的东西真的很少。
也许该随笔还有很多错误的地方,谢谢包容提出。
共勉!