C语言学习过程总结(18)——指针(6)

本文详细讲解了数组指针变量的概念,如何初始化存储数组地址,以及二维数组传参本质上是传递首行地址。还介绍了函数指针变量的创建,包括如何通过函数地址调用函数,并指出函数名即为其地址。
摘要由CSDN通过智能技术生成

一、数组指针变量

在上一节中我们提到了,指针数组的存放指针的数组,那数组指针变量是什么呢?

显而易见,数组指针变量是指针

同样类比整型指针变量字符指针变量里面分别存放的是整型变量地址和字符变量地址,我们可以知道,数组指针变量存放的是数组的地址,是可以指向数组的指针变量

int *p1[10];
int (*p2)[10];

对比上面的p1和p2,谁是数组指针变量?

 int (*p2)[10];

这里需要知道:[ ] 的优先级高于 *  

要想是指针变量,就需要* 和 p 先结合,所以需要括号改变运算顺序。

 那 int *p1[10]; 是什么呢?

这就是我们上一节讲的指针数组。

1、数组指针变量如何初始化

数组指针变量是用来存放数组的地址的,那数组的地址是如何获得的呢?  &arr就可以了。

如果需要存放一个数组的地址,就需要存放在数组指针变量中

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

需要注意!

1、

int *p[10] = &arr;

p++ == arr + 1;

2、

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

p + 1 != arr + 1

第二种的p+1是跳过整个数组

 2、二维数组传参的本质

先观察下面的test1 和 test2

void test1(int arr[3][5],int r,int c) {

	for (int i = 0; i < r; i++) {

		for (int j = 0; j < c; j++) {

			printf("%d ", arr[i][j]);
		}

		printf("\n");

	}

}


void test2(int(*p)[5], int r, int c) {

	for (int i = 0; i < r; i++) {

		for (int 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} };
	test1(arr, 3, 5);
	printf("\n");
	test2(arr, 3, 5);
	return 0;
}

两者的输出结果一样

根据数组名就是数组首元素地址这个信息,我们可以推论出,二维数组的数组名就是第一行的地址,也就是第一行数组的地址。

意味着:二维数组的传参本身是传地址,传递的是第一行的一维数组的地址

三、函数指针变量

创建函数指针变量

通过前面多次的类比学习,我们可以和轻易的得到,函数指针变量就是存放函数地址的指针,通过指针去指向函数的地址来调用函数。


	printf("test  = %p\n", test1);
	printf("&test = %p\n", &test1);

我们在刚刚的main函数中加入这两句代码,来帮助我们了解函数是否存在地址

 

可以得出:函数是有地址的,而且因为两者的地址相同,所以函数名就是函数的地址、

拿到了函数的地址,我们就只需要将其存放起来,就可以创建函数指针了

观察下面的代码:

void test() {

	printf("haha\n");
}

int  Add(int x,int y) {

	return x + y;
}

int main() {
	
	void (*pf1)() = test;
	void (*pf2)() = &test;

	int (*pf3)(int x,int y) = Add;
	int (*pf4)(int ,int ) = &Add;

	(*pf1)();
	(*pf2)();


	printf("%d\n", (*pf3)(3,4));
	printf("%d\n", pf4(4,5));

	return 0;
}

对于test和add函数的调用这次没有使用函数名,而是使用函数指针调用。

同时我们还可以通过运行结果看出,使用函数指针去调用函数的时候,是不用解引用指针名的

如: pf4(4,5)  依然得到了正确结果9。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值