二维数组的指针与指针数组

首先,我们知道多维数组顺序存储的创建规则,也就是所谓的行主序(即右边下标率先变化)。假设有下列的声明:
int array[5][6];
int *ptr=&array[3][4];
printf("%d",*ptr);
printf("%d",*++ptr);
printf("%d",*++ptr);
此时打印结果为array[3][4],array[3][5],array[4][0](此处换行)的值.
      由一维数组的数组名为其首地址,可以推断多维数组也是如此。但是事实并非如此。事实上,array[5][6]指的是一个一维数组,其包含了5个元素,每个元素是包含6个整形元素的数组。而array的值是指向它第一个元素的指针。因此,array实际是一个包含了6个整形元素的数组的指针。因此,array+1指的是指向array[5][6]数组第二行的包含6个元素的数组指针。*(array+1)是对其间接访问,标识了一个包含了6个整形元素的子数组。*(array+1)+3是个指向子数组的首个元素往后移3个位置的元素的指针。而*(*(array+1)+3)是对这个指针的间接访问,也就是这个位置储存的元素(也就是array[1][3])。
从这里,我们发现,array[1][3]与*(*(array+1)+3)意义相同。事实上,对于多维数组,下标仍然是一种间接访问表达式,这与一维数组是相同的。
而对于指向数组的指针,这里与一维数组有一些区别。比如下面这个指针:
int *p=array;
本意是想声明一个指向数组的指针,可实际上却无法实现,因为p是一个指向整形的指针,而array是一个指向正型数组的指针,这样显然存在问题。因此,声明指向数组array的指针应该这样:
int (*p)[6];
分析这个声明,我们首先执行对p的间接访问,因此p是一个指针。然后执行下标访问,而因为没有其他的操作符,所以数组的元素类型为缺省状态,因此p是一个指向整形数组的指针。
int (*p)[6]=array;
因此,这个表达式指的是指向array第一行的指针。而p就是一个指向有6个元素的数组的指针。通过将p与整数相加,我们可以使用指针p逐行在array中移动。(注意要避免int (*p)[]=array这种声明,因为数组长度未知,会引发不可预知的错误,而有的编译器并不能发现这一错误)
如果要实现指针的逐元素移动,一下两种声明均可,然后通过增加指针的值来实现逐元素移动。
int *p1=&array[0][0];
int *p2=array[0];
如果作为函数参数传递的多维数组名实际传递的也是指向第一个数组元素的指针,但是因为多维数组每个元素都是一个数组,所以编译器需要获得它的维数。
fun(array);
其中参数array是指向包含6个元素的数组的指针,所以fun的原型可以是下面的两种形式:
fun(int (*mat)[6]);
fun(int mat[][6]);
因此,多维数组只有第一维可以选择写为数组模式还是指针模式。因此,下面这个表达式并不会出现我们所希望的结果,它实际上是一个指向整型指针的指针。
fun(int **mat);

同样,你还可以声明指针数组。
int *arr[6];
分析这个表达式,首先执行下标引用,因此arr是个包含10个元素的数组。在取得一个元素后,执行间接访问,其结果是一个整型值。因此,arr是一个包含元素为指向整形的指针的数组。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值