以下错误代码容易产生混乱:
int a[3][5] = {1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[5];
p = a[0]; //error
分析:
int (*p)[5];
p不解指针是指向数组的指针,解指针后是指向元素(也就是int类型)的指针,都是指针。其实数据的定义和声明原理上有些相似,我们可以把int (*p)[5]看成一个数组的声明,相当于int a[5],所以*p和a都是一个数组,那么p就是指向这个数组的指针,所以p = &a。当执行p = &a后,p 和 *p值是一样的,因为数组的名字a其实是这个数组的起始地址,而指向数组的指针的值也是数组的起始地址,只不过类型不一样。
类型不一样,就会导致加上一个数后,实际的值变化是不一样的:
p + n得到的值是p + n * 5 * sizeof(int);
而*p + n 得到的值是 *p + n * sizeof(int);
这和指向基本类型的指针的道理是一样的:
int a = 5;
int *p = &a;
char *p1 = (char *)p;
p + n得到的值是 p + n * sizeof(int); p1 + n 得到的是 p + n * sizeof(char);
对p的赋值:
从概念上讲,p是指向数组的指针,如果有int a[3][5], p = a[0]是不对的,因为a是指向数组的数组类型,a[0]是数组类型,应该把数组的地址赋值给指向数组的指针;所以正确的赋值应该是:p = &a[0]