初识指针数组、数组指针

声明:学习过程中的笔记,不足之处请指教

两者的含义

指针数组int* arr[10];  用来存放指针的数组。

解释: arr 先与“[ ]”结合,构成一个数组的定义,数组名为 arr。 

如果搞不清楚运算符的优先级,那么就加上小括号(),比如定义一个指针数组,可以写成

char *(arr[10]), 这里我们要的是一个数组,所以把arr[10]括起来。

这个数组里面有10个元素,10个元素都是指针类型

数组指针int (*p)[10];  用来存放数组的地址。

解释:p 先和 * 结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。

这里我们要的是一个指针,所以把 *arr 括起来。
p指向一个数组,该数组有10个元素,每个元素是 int型。

注意:p的类型是:int (*)[10];   

          p是指向一整个数组的,数组有10个元素,int [10];

          p+1 会跳过10个元素,所以在数组遍历的时候要注意,例如:

int arr[10];
int (*p)[] = &arr;

/*
&arr --> int(*)[10]
arr  --> int*
*/
//所以 &arr + 1 也是跳过整个数组,但是arr + 1 是指向下一个元素

指针数组应用

指针数组有什么用呢?

既然指针数组是用来存放指针的数组,那么最能想到的用法,就是将一些变量的地址存放进一个数组里面。

在给定一个数组里面,我们除了可以使用下标法去遍历里面的成员之外,还可以利用地址下标找。

例子1: 对于单个一维数组

#include <stdio.h>
 
const int MAX = 3;
 
int main ()
{
   int  var[] = {10, 100, 200};
   int i, *ptr[MAX];
 
   for ( i = 0; i < MAX; i++)
   {
      ptr[i] = &var[i]; /* 赋值为整数的地址 */
   }
   for ( i = 0; i < MAX; i++)
   {
      printf("Value of var[%d] = %d\n", i, *ptr[i] );
   }
   return 0;
}

例子2:对于多个一维数组

#include <stdio.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 6,7,8,9,10 };
	int arr3[] = { 11,12,13,14,15 };

	int* parr[3] = {arr1,arr2,arr3};//这样就和二维数组一个意思了

	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 5; j++) 
		{
			printf("%3d",(*parr[i] + j));// j 指向一维数组的元素的下标
			//printf("%3d", parr[i][j]);// *(p+i) --> p[i]
		}
		printf("\n");
	}

	return 0;
}

例子2的解释图:

通过三个数组名,可以分别找到该数组名对应的首元素地址。(比如通过数组名arr1,找到arr1数组首元素1的地址) 

强调:

数组名通常表示的都是数组首元素的地址
但是有2个例外:
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小
2. &数组名,这里的数组名表示的依然是整个数组,所以&数组名取出的是整个数组的地址

数组指针应用

 例子1:

int main()
{	
	int arr[] = {1,2,3,4,5};
	/*指针数组
	int* p = arr;
	for (int i = 0; i < 5; i++)
	{
		printf("%d ",*(p+i));
	}
	*/

	/*数组指针
	对于简单的例子不推荐这个写法
	int (*p)[5] = &arr;   //将数组arr的地址赋值给数组指针变量p
	for(int i=0;i<5;i++)
	{
        //printf("%d ",(*p)[i]);
		printf("%d ",*(*p+i));//p指向数组arr, *p相当于数组名,
	}            数组名又是首元素地址,所以*p本质是数组首元素地址
	*/

	return 0;
}

 解释:

既然数组指针指向的是数组,那数组指针中存放的应该是数组的地址。

我们知道,pa是数组指针,指向arr数组,里面存的是数组arr的地址。

既然拥有了数组arr的地址,解引用就可以拿到这个数组。(就相当于拿到了一个数组的数组名)即:

*pa	//数组的地址解引用,就拿到了这个数组

 拿到了数组名*pa,要去找数组内每个元素,就可以按照正常数组元素的访问来拿到每个元素。即:

(*pa)[0];	//数组的第一个元素

因为 *pa 就等于找到了这个数组(*pa==arr)。

arr是数组名,数组名是首元素地址。

arr + i 就是从arr数组首元素的位置向后移动i,指向下标为i的元素。

再次解引用,就是第i个元素了。即:

*(*pa+i)

例子2:

void print1(int arr[3][5], int r, int c)
{
	int i = 0;
	for (i = 0; i < r; i++)
	{
		int j = 0;
		for (j = 0; j < c; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}//常规写法

void print2(int (*p)[5], int r, int c)
{
	int i = 0;
	for (i = 0; i < r; i++)
	{
		int j = 0;
		for (j = 0; j < c; j++)
		{
			//printf("%d ", *(*(p + i) + j));//*(p + i)表示行
			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 };
	print1(arr, 3, 5);
	print2(arr, 3, 5);

	return 0;
}

小结:

引入数组指针后,我们就有两种方案来访问数组元素了,一种是使用下标,另外一种是使用指针。

1) 使用下标

也就是采用 arr[i] 的形式访问数组元素。如果 p 是指向数组 arr 的指针,那么也可以使用 p[i] 来访问数组元素,它等价于 arr[i]。

2) 使用指针

也就是使用 *(p+i) 的形式访问数组元素。另外数组名本身也是指针,也可以使用 *(arr+i) 来访问数组元素,它等价于 *(p+i)。

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

漏洞嵌入式

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值