数组指针(指针数组)

目录

指针数组: 

数组指针:

二维数组的传参: 


 

指针数组: 

       整形数组里面存放的元素是整形,同理,指针数组里面存放的是指针。

       先看一下指针数组: 

int main()
{
	int arr[10] = { 0 };//整形数组
	char ch[5] = { 0 };//字符数组
	int* parr[4];//存放整形指针的数组 - 指针数组
	int a = 10;
	int b = 20;
	int c = 30;
	int* p[3] = { &a,&b,&c };

	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,4,5,6,7 };
	int* pa[] = { arr1,arr2,arr3 };//因为每个数组名就是地址,所以就是指针类型
	return 0;
}

       指针数组本质上是数组,数组里面存放的是指针,所以要加*,由于数组名是首元素地址,所以相当于指针。   

       这是指针类型的数组,数组里面存档的是指针。

       我们来用指针数组模拟二维数组:  

       实际上并非是二维数组,因为每个指针不是连续存放的。 

数组指针:

       我们知道整形指针,字符型指针,正如有整形数组,字符型数组一样,也有数组指针。先看看如何用指针打印出每个元素:

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = arr;
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(p + i));//用指针打印出数组每一个元素
	}
	return 0;
}

      上面就是相当于定义了一个整形指针,我们来看数组指针的具体实现:

int main()
{
	int arr[10] = { 1,2,3,4,5 };
	int(*parr)[10] = &arr;//因为我们知道,&arr是整个数组的地址

	//但是整个数组的地址是数组指针,并不是整形或其他类型,因此我们需要使用数组指针来接受
	//int *parr[10],因为[]的优先级大于*,这样写相当于指针数组
	return 0;
}

 

       我们一定要知道&arr和arr(arr是数组名)的区别,arr是取出数组的首元素地址;&arr是取出整个数组的地址,因为数组指针指向整个数组,指针的步长就是一个整个数组,所以将parr+1下一个指向就是数组末元素的下一个地址。

int main()
{
	int arr[10] = { 0 };
	int* p1 = arr;
	int(*p2)[10] = &arr;

	printf("%p\n", p1);
	printf("%p\n", p1 + 1);

	printf("%p\n", p2);
	printf("%p\n", p2 + 1);

	return 0;
}

 

       因为地址加上元素个数就是下一个地址,解引用后就会找到这个元素。 我们来看数组指针的使用:

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int(*p)[10] = &arr;
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", (*p)[i]);//p是数组的地址,想拿到元素只能解引用
	}      
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(*p + i));//*p == arr->数组名,相当于首元素地址所以要解引用
	}                         
	return 0;
}

       当p加上星号以后,就相当于把取地址&arr的&抵消掉了,之后就相当于数组名了,之后在后面加上下标,就把每一个元素打印出来了;之后第2种方法:*(*p+i)就相当于数组名是地址,解引用后找到每一个元素,加i就相当于下一个元素。
       我们在给出一个比较绕的代码:

int main()
{
	char* arr[5];

	char* (*p)[5] = &arr;
	return 0;
}

二维数组的传参: 

        当我们对二维数组进行函数传参时,因为二维数组的首元素是第一行的地址,因为二维数组可以当做几个一维数组组成。所以当使用二维数组进行传参时,我们传入数组名,就是第一行一维数组的地址,所以函数要使用数组指针进行接收。

void print2(int(*p)[5], int r, int c)
{
	int i = 0, j = 0;
	for (i = 0; i < r; i++)
	{
		for (j = 0; j < c; j++)
		{
			printf("%d", *(*(p + i) + j));
		}
		printf("\n");
	}
}
int main()
{
	//数组指针一般不用于一维数组,没有什么实际用途,用指针就可以表示
	int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
	//所以一般在传参时使用
	print2(arr, 3, 5);
	return 0;
}

       一般数组指针是在二维数组上使用的,特别是函数传参。因为此时数组指针指向的数组个数为5,所以先对其解引用*找到上一个数组的地址(本质上就是二级指针),之后再让上一个数组地址找到它每个对应的元素,最后进行解引用即可。 

       我们可以观察每一行的地址。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值