数组指针与指针数组

数组指针和指针数组

s的类型是二维数组,但是其本身也是一个一维指针(数组指针),其静态类型是char(*)[10],每次移动是10个char长度也就是10字节。其解引用后静态类型是char*,每次移动是1个char长度也就是1字节。

值得注意的是,类似函数指针,s、*s、&s其值都是一样的,都是该二维数组首个元素的地址,因此不能将数组名当成是一个值为元素首地址的常规变量!因为永远无法取得其地址。

因此,下面代码中将s赋值给双重指针ps是完全错误的;双重指针要经过两次间接跳转访问元素:比如ps的值为0x0000ff33*ps首先跳转到该位置后取其值,比如说那个地址的值为0x0000eedd,将*ps当成字符串输出时,会再次跳转到地址为0x0000eedd的位置取出char,完全乱了。

而作为对比,数组指针解引用不会跳转,只会修改其步幅跨度

1
2
3
4
5
6
char s[][10] = { "aaa", "bbb", "ccc" };
char** ps = (char**)s;
cout << (decltype(*s))*ps << endl; // OK 强行改变了类型
cout << *(char(*)[10])ps << endl; // OK 强行改变了类型
cout << (char(&)[10])*ps << endl; // OK 强行改变了类型
cout << *ps << endl; // ERROR! 两次跳转乱了

这里s是一个指针数组(确定类型要从内而外,从右向左),因此可以将其赋给双重指针,他们取char都要经过两次跳转。

1
2
3
const char* s[] = { "aaa", "bbb", "ccc" };
char** ps = (char**)s;
cout << *ps << endl; // OK