指针数组与数组指针---傻傻分不清楚?

文章介绍了C语言中指针数组和数组指针的概念,通过实例展示了如何创建和使用它们。指针数组是存放指针的数组,可以用来存储变量地址或字符串首字符地址。而数组指针则是一个指向数组的指针,常用于二维数组的处理。文中还探讨了如何在函数参数中使用数组指针来传递和操作数组,特别是二维数组的情况。
摘要由CSDN通过智能技术生成

1.指针数组

什么是指针数组呢?
我们通过以前学过的数组进行类比:

  • 整形数组是存放整形的数组
  • 字符数组是存放字符的数组
  • 所以,指针数组是存放指针(地址)的数组

整形数组的书写形式是int arr[10],字符指针书写形式是char arr[10],所以字符指针的书写形式是int *arr[10] char* arr[10]
接下来创建一个字符指针数组

int main()
{
	char a = 'a';
	char b = 'b';
	char c = 'c';
	char d = 'd';
	char* arr[4] = {&a,&b,&c,&d};
	return 0;
}

创建了四个char类型变量,将他们取地址放到字符指针数组里,这是最基本的应用

还可以将字符串放到字符指针数组里,字符指针可以存放一个一个字符串中第一个字符的地址,所以这里是将4个字符串首字符的地址存到字符指针数组里

int main()
{

	char str1[] = "hello";
	char str2[] = "world";
	char str3[] = "byebye";
	char str4[] = "world";

	char* arr[4] = {str1,str2,str3,str4};
	return 0;
}

在这里插入图片描述

还可以用一维指针数组模拟二维数组

#include <stdio.h>
int main()
{
	int arr1[5] = { 1,2,3,4,5 };
	int arr2[5] = { 2,3,4,5,6 };
	int arr3[5] = { 3,4,5,6,7 };
	int arr4[5] = { 5,6,7,8,9 };
	int arr5[5] = { 0,1,0,2,0 };

	int* arr[5] = { arr1,arr2,arr3,arr4 ,arr5};
	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			printf("%d ", *(*(arr + i) + j));
		}
		printf("\n");
	}
	return 0;
}

前面说过,对于一个指针p , *(p+i)p[i]等价
所以上述程序中的*(*(arr + i) + j)也可以写成arr[i][j],也就是如二维数组一样的写法
这个指针数组的结构:
在这里插入图片描述


2.数组指针

对于数组指针,还是类比其他类型指针

  • 整形指针是一个指向整形变量的指针
  • 字符变量是一个指向字符变量的指针
  • 所以数组变量就是一个指向数组的指针
  • 整形指针的类型是int*,字符指针的类型是char*,所以数组指针的类型就是int(*)[10]
char ch = 'w';
char *pc = &ch;

int num = 10;
int* pi = &num;

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

在这个整形数组指针,*先与pa结合:(*pa),所以int(*pa)[10]是一个指针

在这里赋给数组指针的是数组名取地址,那么数组名和数组名取地址有什么区别呢?请点击跳转另一篇文章:数组与地址,数组名到底是什么?


数组指针到底怎么用呢?

之前如果要输出一个整形数组,我们可以使用指针,这里的指针通常是数组元素首地址

但是如果非要用数组指针输出数组中的元素也是可以的

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

这里的p是一个数组指针,先将解引用*p,得到数组,然后通过下标访问(*p)[i])就可以得到数组元素了

但是这样做是很别扭的,不如直接用整形指针输出

其实 数组指针在一位数组中用的不多,在二维数组中会用到

在以往的对于二维数组的传参,定义函数时,在参数列表中最简单的写法是直接以二维数组的形式传形参

void print(int arr[3][4], int x, int y) //直接以二维数组的形式写是最简单的
{
	for (int i = 0; i < x; i++)
	{
		for (int j = 0; j < y; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}
int main()
{
	int arr[10] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };
	print(arr, 3, 4);
}

但是,对于一位数组int arr[10],如果在函数中想要接受它,不但可以以数组的形式接受,用一个一级指针接受也是可以的


void printf(int arr[10],int len)  //可以用数组的形式接收
{
	;
}

void printf(int *arr,int len) //也可以用指针的形式接收
{
	;
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10};
	print(arr,10);
}

如果也想要用一个指针变量去接收二维数组传参就略有不同了

函数实参传一个二维数组名过去,数组名是数组首元素地址,所以二维数组数组名就是一个一维数组的地址,这个二维数组名其实就是一个数组指针,所以在函数中要用一个数组指针去接收

void print(int(*arr)[4],int x,int y)  //用一个数组指针去接收
{
	for (int i = 0; i < x; i++)
	{
		for (int j = 0; j < y;j++)
		{
			printf("%d ", (*(arr+i))[j]);
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][4] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };
	print(arr, 3, 4);
}

学过了数组指针和指针数组,看看下面这些都是什么?

int arr[5];
int *parr1[10];
int (*parr2)[10];
int (*parr3[10])[5];
  1. int arr[5],是一个长度为5的整形数组
  2. int *parr1[10],是一个整形指针数组,长度为10,里面存放整形指针
  3. int (*parr2)[10],是一个数组指针,parr2指向一个长度为10的整形指针
  4. int (*parr3[10])[5],这个比较复杂,一步一步分析,首先看名称parr3先与[10]结合,所以这是一个数组,长度为10,然后剩下int(*)[5],所以在数组parr3中存放的是类型为int(*)[5]的数组指针,它指向一个长度为5的整形数组。
  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

疯癫了的狗

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

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

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

打赏作者

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

抵扣说明:

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

余额充值