一个数组的名称,就是第一个元素的地址,实际上可以看成一个指向数组第一个元素的指针,而数组名加上[num],则代表数组第num个元素的内容,可以等价为数组名前加*(读作间接值符号会有助于理解)。举个例子:
int a[5] {1,2,3,4,5};
int * b = a;
cout << a << endl;
cout << b << endl;
cout << a[0] << endl;
cout << *b << endl;
运行上面的代码片段,我们可以得到两组相同的结果,因此,在面对数组和指针时,我们不妨把[]与*等效。那么对于指向指针的指针等更复杂的情况如何搞清楚关系呢,我认为可以使用画方框的办法。
先举一个简单的例子:
int * a;
int ** b;
方框图用方框表示存储单元,箭头表示指向关系。第一行代码可以用方框图表示为:
第二行代码可以用方框图表示为:
举个更复杂的例子mixtypes.cpp(来自C++PrimerPlus第六版):
#include <iostream>
using namespace std;
struct antarctica_years_end{
int year;
};
int main(){
antarctica_years_end s01, s02, s03;
s01.year = 1998;
antarctica_years_end * pa = &s02;
pa -> year = 1999;
antarctica_years_end trio[3];
trio[0].year = 2003;
cout << trio -> year << endl;
const antarctica_years_end * arp[3] = {&s01, &s02, &s03};
cout << arp[1] -> year << endl;
const antarctica_years_end ** ppa = arp;
auto ppb = arp;
cout << (*ppa) -> year << endl;
cout << (**(ppb+1)).year << endl;
return 0;
}
const antarctica_years_end * arp[3] = {&s01, &s02, &s03};
这句代码,定义了一个指针数组,数组中的每个元素都是一个指针,指向一个antarctica_years_end结构类型的变量,那么我们可以根据这个关系画(对于arp)出如下方框图:
第一个存储单元名字为arp,第二个存储单元是arp数组中第一个元素(指针),该元素指向一个antarctica_years_end结构类型的值。这样我们也就不难理解下面这句代码:
const antarctica_years_end ** ppa = arp;
这里是创建一个指向antarctica_years_end指针类型的指针,化成方框图我们可以很清楚的看出实际上名称为ppa和arp的两个存储单元中存储了相同的一个地址,这个地址都指向arp数组的第一个元素。
cout << (*ppa) -> year << endl;
cout << (**(ppb+1)).year << endl;
将[]与等效,每一个其实就是方框图向箭头方向前进一个方框即可。