C++声明指向数组的指针

一、问题

下面这些声明合法吗?

	int vector[10], *vp = vector;
	int matrix[3][10], *mp=matrix,
	

二、答案

第1个声明是合法的。它为一个整型数组分配内存,并把vp声明为一个指向整型的指针,并把它初始化为指向 vector数组的第1个元素。 vector和vp具有相同的类型:指向整型的指针

第2个声明是非法的。它正确地创建了 matrix数组,并把mp声明为一个指向整型的指针。但是,mp的初始化是不正确的,因为matrix并不是一个指向整型的指针,而是一个指向整型数组的指针。正确的初始化方法是

int matrix[3][10];
int (*mp)[10] = matrix;

三、如何声明一个指向整型数组的指针

int(*p)[10];

这个声明比我们以前见过的所有声明更为复杂,但它事实上并不是很难。你只要假定它是一个表达式并对它求值。下标引用的优先级高于间接访问,但由于括号的存在,首先执行的还是间接访问。所以,p是个指针,但它指向什么呢?接下来执行的是下标引用,所以p指向某种类型的数组。这个声明表达式中并没有更多的操作符,所以数组的每个元素都是整数。

声明并没有直接告诉你p是什么,但推断它的类型并不困难——当我们对它执行间接访问操作时,我们得到的是个数组,对该数组进行下标引用操作得到的是一个整型值。所以p是一个指向整型数组的指针
我们在声明中加上初始化后是下面这个样子

int(*p)[10] = matrix;// 一个指针,它指向一个有10个int元素的数组

它使p指向matrix的第1行。
p是一个指向拥有10个整型元素的数组的指针。当你把p与一个整数相加时,该整数值首先根据10个整型值的长度进行调整,然后再执行加法。所以我们可以使用这个指针一行一行地在 matrix中移动。

四、实例

现在,我们来观察一个矩阵

int matrix[3][10] ;
...
Func(matrix);

这里,参数 matrix的类型是指向包含10个整型元素的数组的指针。Func的原型应该是怎样的呢?

我们可以使用下面两种形式中的任何一种

void Func( int (*mat)[10])
void Func( int mat[][10])


在这个函数中,mat的第1个下标根据包含10个元素的整型数组的长度进行调整,接着第2个下标根据整型的长度进行调整,这和原先的 matrIx数组一样。这里的关键在于编译器必须知道第2个及以后各维的长度,才能对各下标进行求值。因此在原型中必须声明这些维的长度。第1维的长度并不需要,因为在计算下标值时用不到它。在编写一维数组形参的函数原型时,你既可以把它写成数组的形式,也可以把它写成指针的形式。

但是,对于多维数组,只有第1维可以进行如此选择。尤其是,把Func写成下面这样的原型是不正确的

void Func( int **mat,int row,int col)


它把mat声明为一个指向整型指针的指针,它和指向整型数组的指针并不是一回事。

可以进行强制转换如下调用。

	Func((int**)matrix,3,3);

其他实例

在该例中,指向有 10 个 int 元素的数组的指针会被初始化为 NULL。然而,如果把合适数组的地址分配给它,那么表达式 *arrPtr 会获得数组,并且(*arrPtr)[i] 会获得索引值为 i 的数组元素。根据下标运算符的规则,表达式(*arrPtr)[i] 等同于 *((*arrPtr)+i)。因此,**arrPtr 获得数组的第一个元素,其索引值为 0。 

    int (* arrPtr)[10] = NULL;   // 一个指针,它指向一个有10个int元素的数组    
    int matrix[3][10];            // 3行,10列的数组
                              // 数组名称是一个指向第一个元素的指针,也就是第一行的指针
    arrPtr = matrix;            // 使得arrPtr指向矩阵的第一行
    (*arrPtr)[0] = 5;       // 将5赋值给第一行的第一个元素
    arrPtr[2][9] = 6;           // 将6赋值给最后一行的最后一个元素
    ++arrPtr;                   // 将指针移动到下一行
    (*arrPtr)[0] = 7;           // 将7赋值给第二行的第一个元素

在前文 arrPtr 的声明语句(int(*arrPtr)[10]=NULL;)中,删除其中标识符 arrPtr,就可得到 int(*)[10],即对应的数组指针类型。然而,为了提高可读性和灵活性,可以利用 typedef 为所用的类型定义一个简单的名字:

	typedef int ARRAY_t[10];    // 定义一个“具有10个元素数组”类型名称
	ARRAY_t  array,                     // 具有该类型的数组
		*arrPtr;               // 一个指向该数组类型的指针
	arrPtr = (ARRAY_t *)array;  // 使得arrPtr指向array

 参考:

C语言数组指针和指针数组

如何将二维数组作为函数的参数传递_manba-CSDN博客_二维数组 函数参数

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值