0
点赞
收藏
分享

微信扫一扫

指针数组与数组指针 — 不是twins的twins

小云晓云 2022-01-22 阅读 72

目录

一,指针数组

1.1指针数组基本知识

1.2指针数组实用案例分析

 二,数组指针

1.1数组指针基本知识

2.2数组指针应用例子 

2.2.1反面例子

 2.2.2正确例子


如题目所示,今天我们将认识的是一对像双胞胎但却不是双胞胎的指针内容。

一,指针数组

1.1指针数组基本知识

我们知道整型数组,知道字符数组,那么指针数组是不是跟他们连个差不多呢,答案是是的,指针数组,就是存放指针的数组,该数组的每一个元素都是指针。如下代码所示:

	int a[10];//整型数组
	char a1[10];//字符数组
	int* arr1[10];//(整型)指针数组

当然 ,不可或缺的,因为数组元素也需要有数据类型,这里展示的是整型指针数组。

1.2指针数组实用案例分析

我们通过一个例子来学习指针数组的基本用法。

#include<stdio.h>
int main()
{
	int a1[] = { 1,2,3,4 };
	int a2[] = { 2,3,4,5 };
	int a3[] = { 3,4,5,6 };
	int* pa[3] = {a1,a2,a3};
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 4; j++)
		{
			printf("%d ", pa[i][j]);//pa[i] = *(pa+i)                         
		}
		printf("\n");
	}
	return 0;
}

如上图所示,pa为一个拥有三个元素的整型指针数组,而三个元素分别为三个数组的数组名,我们知道,指针数组存放的一定是指针;而我们又知道,一般情况下,数组名代表数组首元素地址,所以这样做是可行的。

那么我们想将三个数组的元素全部打印。就需要找到每一行的所有元素,我们的方法是,先通过指针数组找到每一组数据,然后每一组挨个遍历。

当然不止一种实现打印的方法,后面我们会一一涉及。

 二,数组指针

1.1数组指针基本知识

可能大家都有疑问,什么叫数组指针,毕竟见过字符指针,见过整型指针,就是没见过数组指针,不着急,下面的代码将为你解惑:

//数组指针
int main()
{
	int a = 2;
	int* pa = &a;//整型指针
	char b = 'v';
	char* pb = &b;//字符指针
	int arr[10] = {0};
	int(*pc)[10] = &arr;//数组指针,这里由于[]操作符的优先级高于 * 操作符,
	                   //所以要加上(),将pc和*强制匹配,否则就变成了下面指针数组了
	int* arr[10] = arr;//指针数组
}

整型指针和字符指针容易理解,就是该指针指向的内容是整型和字符型,那么同样的,指向的内容是数组的指针,称为数组指针。

2.2数组指针应用例子 

2.2.1反面例子

接下来我们来学习一个数组指针的反面例子:

//反面例子
//用数组指针打印,即传递整个数组的地址给指针变量
#include<stdio.h>
void print2(int (*pb)[8],int b)
{
	int i = 0;
	for (i = 0; i < b; i++)
	{
		//printf("%d ",(*pb+0)[i]);//(*pb+0)即代表该数组的第一个元素,[i]代表第一个元素中的元素。
		                           //所以这样写是很别扭而且没必要的
		                           //那真正用这种情况的是:二维数组
		//printf("%d ",pb[0][i]);
		printf("%d ", *((*pb)+i));//这里能看出的是+运算符的优先级高于*
	}
}
int main()
{
	int arr[] = {1,2,3,4,5,6,7,8};
	int sz = sizeof(arr) / sizeof(arr[0]);
	//print1(arr,sz);
	print2(&arr,sz);
	return 0;
}

这里我们想实现的目标是用函数打印一维数组中的所有元素。可以看到上述代码,将一维数组在全部元素的地址传递给数组指针,然后用数组指针来打印,可以看到数组指针打印是比较繁琐的。虽然可以说有三种方式去打印,但是这三种方式远远复杂于只传递数组名,这样子的一般传参习惯。如下代码所示即为只传递数组名的方式:

void print1(int *pa,int a)
{
	int i = 0;
	for (i = 0; i < a; i++)
	{
		printf("%d ",*(pa+i));
	}
}
//void print1(int pa[], int a)
//{
//	int i = 0;
//	for (i = 0; i < a; i++)
//	{
//		printf("%d ", pa[i]);
//	}
//}

当然,因为这里的三个打印稍微有点难理解,所以我们放在正确的例子帮助大家理解呦! 

 2.2.2正确例子

好的,既然前面说了,数组指针不能随便乱用,否则可能达到相反的效果。那么到底在哪里才可以将其用在实处呢?我们知道的是,数组指针,首先是一个指针,其次是一个元素均为某类型的数组,那么如果我们将指针指向某个二维数组,二维数组里面的每一行不就是数组指针里面的数吗,是的,代码如下:

#include<stdio.h>
void print(int (*pa)[4],int r,int c)//接收二维数组传参,因为属于数组指针,所以需要给出首地址()的元素个数
{
	int i = 0;
	for (i = 0; i < r; i++)
	{
		int j = 0;
		for (j = 0; j < c; j++)
		{
			//printf("%d ", *(*(pa+i)+j));
			//printf("%d ", pa[i][j]);
			printf("%d ",(*(pa+i))[j]) ;
         //总结:打印数组指针,一共有三种打印方法。
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
	//int(*pa)[3][4] = &arr;//这种写法一般不会有,可以称为错误的写法
	print(arr,3,4);//二维数组传参,传递的首元素其实是首行元素的地址
	return 0;
}

在该代码中,二维数组传递数组名,即代表传递的是首行元素的地址,所以形参在接收时则需要用数组指针去接收,并且当接受的是一维数组时,必不可少的该行元素的个数是不能缺的。

看到这,你是否觉得也觉得指针数组和数组指针是开头说的那样,不是twins的twins呢?

关于指针数组和数组指针的内容就到这儿了,如果文章有错误或不妥之处,欢迎留言评论哦!

举报

相关推荐

0 条评论