C语言中指针和多维数组
数组名是特殊的指针
数组是一个特殊的指针,多维数组也是更为复杂的数组,它们的关系是什么样的呢?
我们通过一个简单的例子来比较形象的了解指针和多维数组:
int a[2][3];这是一个2*3的二维数组,首先我们清楚
数组名就是指向数组首元素的常量指针(它不可以指向其他部分,可以对指向的元素进行任意修改);其次C语言中所谓的多维数组,即是数组的数组,2*3的二维数组,本质上为2个有包含3个int的数据的数组。所以现在我们就可以解释a的含义:
a == &a[0]那么对于
a[0]也有
a[0] == &a[0][0]这时候我们就也可以得到另一个特殊的结论:
a == a[0],字面上看起来很难理解,这是因为对于一个指针它指向一个元素有两个要素:第一为这个元素的首地址,第二为这个元素的类型(这也是我们在使用指针所必要要求的必须指向与它类型相同的元素),所以a是一个指向包含3个int元素的数组指针,a[0]是指向int元素的指针。在比较两者时即比较首地址,无疑都是这个二维数组的首地址。但是两者仍然有差别,这种差别是在类型上的,也可谓是根本上的,通过指针的增加运算我们可以看到他们的不同:
通过指针指向多维数组
因为C语言要求指针在指向一个元素时类型必须同元素一致,所以我们想使用指针指向数组时不能简单使用指向
int类型的指针。例如对于二维数组a[2][3]。int main (void) {
int a[2][3];
int (*p)[3] = a;
// int (*p1)[2] = a;这样是不对的,因为C语言二维数组的声明意义为2个长度为3的整型数组而不是相反的
return 0;
}我们使用
int (*p)[3]而不是int *p[3],因为前者表示指向含有三个整数数组的指针,后者为含有3个整型指针的数组。我们也能通过解引用这样的指针对于数组内容进行访问。
我们通过讨论数组名这个特殊的指针来了解指向多维数组的指针,
a == &a[0],所以*a = a[0]为第一个指向长度为3数组的指针;a[0] == &a[0][0],所以*a[0] = a[0][0]这样我们就访问了二维数组的第一个元素,所以**a == a[0][0],我们可以通过多次解引用对多维数组元素进行访问,对于二维数组a[1][2]等价于*(*(a+1)+2)但是通过这样对一个数组进行访问往往会造成费解,而且有时候会出现不安全的现象:
我们惊奇发现b竟然也被修改了!因为我们让pp2指向指针p1。然后因为pp2是指向常量的指针,所以*pp2也可以指向常量b,但是其实*pp2是p1!这时候我们就能通过p1修改常量b的值,这样行为是很危险的!所以不要使用嵌套指针。
浙公网安备 33010602011771号