【C语言】数组和指针的关系


在我第二次学习数组与指针的关系时,我还是对指针和数组的关系不甚了解,打算写下这篇博文整理思路,因此适合对指针和数组的关系初有了解的人阅读


数组名的理解

对于数组名,我们做一个简单的回顾:
数组名是数组首元素的地址,但是有两个例外

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

	printf("&arr[0] = %p\n", &arr[0]);
	printf("arr     = %p\n", arr);

	return 0;
}

运行上述代码后可看到,两个地址相同:
在这里插入图片描述
那两个例外是什么呢???

  1. sizeof(数组名),数组名单独放在sizeof内部,此时数组名代表整个数组
#include <stdio.h>

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%zd\n", sizeof(arr));

	return 0;
}

在这里插入图片描述
2. &数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素
的地址是有区别的)

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	
	printf("%p\n", arr);
	printf("%p\n", arr + 1);
	printf("%p\n", &arr + 1);

	return 0;
}

在这里插入图片描述

(&arr + 1) - (arr) = 00B5F994 - 00B5F96C = 0x28 = 40 - (十个整形)
(arr + 1) - (arr) = 00B5F970 - 00B5F96C = 0x4 = 4 - (一个整形)
可见,&数组名代表整个数组的地址

因此,除sizeof(数组名)和&数组名外,数组名是数组首元素的地址

一维数组传参的本质

由上述数组名的理解可以得到,一维数组传的参数是数组首元素的地址,那为什么不传数组过去呢,因为传递的参数是实际参数的临时拷贝,如果数组太大,那消耗的内存就会过多。

因此:⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式

void test(int arr[])//参数写成数组形式
{
	printf("%d\n", sizeof(arr));
}

void test(int* arr)//参数写成指针形式
{
	printf("%d\n", sizeof(arr));
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	test(arr);
	return 0;
}

指针数组和数组指针

指针数组是存放指针的数组
数组指针是指向数组的指针

int main()
{
	int arr1[3] = { 1,2,3 };
	int arr2[3] = { 4,5,6 };
	int arr3[3] = { 7,8,9 };

	//指针数组
	int* arr[3] = { arr1,arr2,arr3 };
	//数组指针
	int (*pa)[3] = &arr1;

	return 0;
}

!!!注意:[]的优先级要⾼于*号的

在上述代码中
指针数组:int* arr[3]arr先和[3]结合,表示arr代表一个数组,这个数组存放的是int*类型的指针,分别是arr1``arr2``arr3

数组指针:int (*pa)[3]pa先和*结合,表示pa是一个指针,再和int [3]结合,表示这个指针指向了一个存放整形类型的数组

二维数组传参的本质

在写三子棋时,传递的参数是二维数组board[ROW][COL]

void InitBoard(char board[ROW][COL], int row, int col);

那我们根据一维数组传参(可以传递一维数组或者指针)的理解,是否也可以传递指针呢?

⾸先我们再次理解⼀下⼆维数组,⼆维数组其实可以看做是每个元素是⼀维数组的数组,也就是⼆维
数组的每个元素是⼀个⼀维数组。那么⼆维数组的⾸元素就是第⼀⾏,是个⼀维数组。
在这里插入图片描述

所以,根据数组名是数组⾸元素的地址这个规则,⼆维数组的数组名表⽰的就是第⼀⾏的地址,是⼀
维数组的地址,也就是数组指针。
根据上⾯的例⼦,第⼀⾏的⼀维数组的类型就是型就是数组指针类型int [5] ,所以第⼀⾏的地址的类型
int (*)[5]
那就意味着⼆维数组传参本质上也是传递了地址,传递的是第⼀⾏⼀维数组的地址,那么形参也是可以写成指针形式的。

总结:⼆维数组传参,形参的部分可以写成数组,也可以写成指针形式。

函数指针

函数指针和数组指针类似
对于如下代码:

void test()
{
	printf("hehe\n");
}

int Add(int x, int y)
{
	return x+y;
}

void (*pf1)() = &test;
void (*pf2)() = test;
int (*pf3)(int, int) = Add;

&testtest等价

pf1先和*结合,表示pf1是指针,void ()表示指针指向的内容是一个函数指针,这个函数无参数,也无返回值(void

pf3先和*结合,表示pf3是指针,int (int, int)表示指针指向的内容是一个函数指针,这个函数有两个int类型的参数,返回值为int类型

  • 41
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值