指针数组与数组指针

指针数组

指针数组是一个存放指针的数组,即数组中的元素类型均为指针类型。
如 int* arr1[10];
*和[ ]的优先级,[ ]比 *高,因此arr先与[ ]结合,表示其为一个数组,前面的int*表示该数组中存储的元素类型为int*,即数组中的元素类型为整型指针变量。

数组指针

与指针数组完全不同,数组指针是指向数组的一个指针。
int (*p)[10]就是一个数组指针。这里p和*\结合,说明了p是一个指针变量。其指向的是一个大小为10的整形数组。

1.数组的地址和数组首元素的地址

在讲清楚数组指针之前,我们需要先知道数组的地址数组首元素的地址
比如有一个数int a;变量a的地址为多少?答案为&a。即&名称
同理,有一个数组 int arr[10]; 则该数组的地址为&arr。
而该数组首元素的地址为 arr 或者 &arr[0];
我们来看如下代码

int main()
{
	int arr[10] = { 0 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	printf("%p\n", *(&arr));
	printf("%p\n", &arr);

	return 0;
}

执行结果如下图:
在这里插入图片描述
我们发现,四者输出的结果是一样的,其中,前三个都代表arr数组的首元素的地址,第四个代表arr数组的地址,于是,我们就可以得出“数组的地址就是数组首元素的地址”这样的结论吗?
那再看下一段代码:

int main()
{
	int arr[10] = { 0 };
	printf("arr = %p\n", arr);
	printf("arr+1 = %p\n", arr + 1);
	printf("&arr[0] = %p\n", &arr[0]);
	printf("&arr[0]+1 = %p\n", &arr[0] + 1);
	printf("&arr = %p\n", &arr);
	printf("&arr+1= %p\n", &arr + 1);

	return 0;
}

结果如下

在这里插入图片描述
我们那会发现,尽管数组的地址和数组的首地址在数值上相等,但是当他们+1后,地址却不一样。
实际上,arr+1与arr的差值刚好是一个数组元素的大小,在本例子中就是4B,一个整型元素的大小,而&arr+1与&arr的差值,是整个数组的大小,在本例子中就是40B。
这也就说明了,数组的地址和数组首元素的地址的实际意义是不一样的。

2.一维数组中数组指针的应用

知道了数组的地址,我们就可以更好的理解数组指针。
比如有一个数组 int arr[10] = { 0 };
指向该数组的指针应该是 int (*p)[10] = &arr ;
那么,我们怎样用数组指针访问到数组内的元素呢?
请看如下代码:

int main()
{
	int arr[10] = {1,2,3,4,5,6,7,8,9,0};
	int(*p)[10] = &arr;
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", (*p)[i]);
	}
	printf("\n");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);

	}
	printf("\n");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", *(*p + i));
	}
	return 0;
}

输出结果为:
在这里插入图片描述
上面三者的写法是等价的,输出结果也是一样的。
实际上,对于数组指针的应用,二维数组应用更广。

3.二维数组中数组指针的应用
有一个二维数组int arr[3][5]={1,2,3,4,5,6,7,8,9,0},那么该数组名arr代表什么意思呢?
二维数组的数组名代表的是第一行的地址,上述的二维数组,可以看做三个一维数组拼接。那么,arr+1后,指向的应该是下一个一维数组的地址。也就是说,此时的arr,就是一个数组指针。
如何通过数组指针遍历该数组?
请看如下代码

void print_arr(int (*p)[5], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf("%d ", *(*(p + i) + j));
		}
	}
}

int main()
{
	int arr[3][5] = {1,2,3,4,5,6,7,8,9,10};

	print_arr(arr, 3, 5);
	return 0;
}

在上述代码中,p是一个数组指针,则p+i代表第i行的地址,*(p+i)就代表第i行第一个元素的地址,*(p+i)+j就是第i行第j列元素的地址,则*(*(p+i)+j)就是第i行第j列的元素。

懂了以上关于数组指针的讲述后,我们再看一个例子:int (*arr[10]) [5];
这个是什么意思?
首先括号内的arr [10]先结合,表示arr是一个数组,而arr[10]前面的星号,表示该数组是一个指针数组,数组里面存储的元素为指针,每个指针指向的 ,是一个长度为5的int型数组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值