C语言之指针数组与数组指针

指针数组:

本质依然是数组,只是数组中存放的元素都是指针。就比如好孩子,好只是修饰词,无论他好不好,他都是孩子

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };//整型数组
	char ch[5] = { 0 };//字符数组
	int* pr[4];//存放整形指针的数组----指针数组
	char* pr1[5];//存放字符指针的数组----指针数组
	return 0;
}

现在我们通过一个示例感受一下这个过程:

#include<stdio.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,4,5,6,7 };
	int* parr[] = { arr1,arr2,arr3 };//将数组arr1/arr2/arr3存放到指针数组parr中
	int i;
	for (i = 0; i < 3; i++)//对指针数组中的元素进行访问
	//也就是对arr1/arr2/arr3的首元素地址进行访问
	{
		int j = 0;
		for (j = 0; j < 5; j++)//对每个数组中的元素进行访问
		{
			printf("%d ", *(parr[i]+j));//parr[i]输出指针数组的元素等价于输出每个元素的首地址
			//+j之后会对三个数组中的元素进行访问
		}
		printf("\n");
	}
	return 0;
}

输出结果如下所示:
在这里插入图片描述

在这里插入图片描述

数组指针:

本质依然是指针,只不过为指向数组的指针,存放数组的地址
那该如何定义呢?首先,回忆我们之前学过的整形指针和字符指针的定义方法

	int* p = NULL;//p是整形指针---指向整形的指针--可以存放
	char* pc = NULL;//pc是字符指针---指向字符的指针

其次,我们之前还学过对任意数组有:

int arr[10]={0}//arr/&arr[0]为首元素地址
//&arr为整个数组的地址

那么数组指针是不是可以这样表示
在这里插入图片描述
下面那个是数组指针?

1int* p1[10];
2int(*p2)[10];

正确答案是2,那么1为什么不是呢?原因是[]的优先级高于*,对于第一种,p1会优先和[]进行结合,这里的p就成为数组了,但2将p2括起来,强制使p先和进行结合,这里的p是指针。
下面再通过一道题考考你:
如下所示代码中的pa应该怎么进行定义呢?

char* arr[5];
pa = &arr;

采访了一一些同学后,有以下三种答案,那么到底哪种是正确的呢?

A:char(*pa)[5];
B:char* (*pa)[5];
C:char(**pa)[5];

正确答案为同学B的,下面我们来说说该怎么正确定义:
先对代码进行分析:

char* arr[5];//定义字符指针数组,元素个数为5个
pa = &arr;//将数组arr的地址存放到pa中

我们想定义一个数组指针,那么首先得指明pa是一个指针即为pa,又因为上文我们提到,[]的优先级高于,因此我们赶快将*pa括起来,即为(*pa),又因为arr本身是数组,那么指针pa需要指明数组的元素,即为(*pa)[5],最后在最面加上数组的类型,可以类比整形指针的定义方法。

数组名VS&数组名:

数组名代表数组首元素地址,&数组名代表整个数组的地址。
下面我们通过一段代码验证一下:
在这里插入图片描述arr+1跳过的字节长度为一个int,而&arr+1跳过的字节长度为10个int

一维数组与数组指针的结合使用:

举例:

#include<stdio.h>
int main()
{
	int arr[10] = { 2,34,51,2,3,10,9,11,21,0 };
	int(*pa)[10] = &arr;
	int i;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", (*pa)[i]);
		//printf("%d ",*(*pa+i));
		//(*pa)[i],*pa==arr先对指针进行解引用操作,再找数组中的元素
	}
	return 0;
}
2 34 51 2 3 10 9 11 21 0

看到这里,有的小伙伴会觉得干嘛要搞得这么麻烦啊?直接用指针输出就可以了啊

#include<stdio.h>
int main()
{
	int arr[10] = { 2,34,51,2,3,10,9,11,21,0 };
	int* p = arr;
	int i;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(p+i));
	}
	return 0;
}

在这里插入图片描述是的,这样确实也能很好的输出,但数组指针的实用性并不体现在一维数组,而是二维及二维以上数组,下面我们通过示例验证:

对于二位数组元素的输出,常规方法:
#include<stdio.h>
void print1(int arr[3][5], int x, int y)//传递数组形式,行,列,参数是数组
{
	int i, j;
	for (i = 0; i < x; i++)
	{
		for (j = 0; j < y; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,0},{0,9,8,7,6} };
	print1(arr, 3, 5);//传递数组名,行,列
	return 0;
}

在这里插入图片描述

使用数组指针的方法:
#include<stdio.h>
void print2(int(*p)[5], int x, int y)//参数是指针,传递的为第一行的地址
{
	int i = 0;
	
	for (i = 0; i < x; i++)
	{
		int j = 0;
		for (j = 0; j < y; j++)
		{
			printf("%d ", *(*(p + i) + j));//*(p+i)找到该二维数组的确定的行,+j之后才能找到每行的每个元素
			//printf("%d ", *(p + i) [j]);
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][5] = { {1,2,3,4,5},{6,7,8,9,0},{0,9,8,7,6} };
	print2(arr, 3, 5);
	return 0;
}

在这里插入图片描述怎么理解二维数组呢?
在这里插入图片描述
最后我们通过示例区分一下这几个概念:

int arr[5];//arr是含有5个元素的整型数组
int* parr1[5];//parr1是一个数组,数组有10个元素,每个元素的类型是int*,parr1是指针数组
int(*parr2)[10];//parr2是一个指针,该指针指向了一个数组
			   //数组中有10个元素,其类型为int,parr2为数组指针
int(*parr3[10])[5];//parr3是一个数组,该数组有10个元素,每个元素是一个数组指针
				   //该数组指针指向的数组有5个元素,每个元素是int
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从未止步..

谢谢你的打赏,我会继续努力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值