对C中转移表(函数指针数组)和 指向函数指针数组的指针(函数指针数组指针)的一些理解

本文主要介绍了C语言中转移表(函数指针数组)和指向函数指针数组的指针(函数指针数组指针)。详细解释了函数指针数组的概念,说明转移表是其用途,还通过代码展示了转移表的用法。同时对函数指针数组指针的概念、声明及用法进行了阐述。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对C中转移表(函数指针数组)和 指向函数指针数组的指针(函数指针数组指针)的一些理解

1).转移表(函数指针数组)

函数指针数组: 首先明确函数指针数组是一个数组 , 这个数组中的元素类型是指针 , 是指向函数的指针(函数指针)
转移表 : 就是一个存放函数指针(地址)的一个函数指针数组(转移表也就是函数指针数组的用途)

那么我们来看一下哪个是函数指针数组呢

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

答案是p1 , 因为p1先与[10]结合说明它是一个数组 , 是个什么数组呢 , 我们看到(*p1[10]) , 又与 * 结合说明是一个指针数组 , 那么又是什么类型的指针呢 , (*p1[10]])() , 后面又与 () 结合说明是指向函数的指针(函数指针) , int (*p1[10]])() , 再看最前面的int 说明这个函数是返回值为int的函数 , 结合起来就叫 函数指针数组

我们再通过代码来看一下:

#include<stdio.h>
#include<stdlib.h>
int add(int a, int b) {
	return a + b;
}
int sub(int a, int b) {
	return a - b;
}
int mul(int a, int b) {
	return a * b;
}
int Div(int a, int b) {//不考虑b=0的情况
	return a / b;
}
int main() {
	int a = 4;
	int b = 2;
	printf("%d+%d=%d\n", a, b, add(a, b));
	printf("%d-%d=%d\n", a, b, sub(a, b));
	printf("%d*%d=%d\n", a, b, mul(a, b));
	printf("%d/%d=%d\n", a, b, Div(a, b));
	system("pause");
	return 0;
}

在这里插入图片描述
可以看出 , 我们通过直接调用函数的方式 , 得到了4与2加减乘除的结果 , 但又没有其他方法实现呢?
答案是肯定的 , 可以利用转移表(函数指针数组)来实现
让我们再看运行一下这段代码

int add(int a, int b) {
	return a + b;
}
int sub(int a, int b) {
	return a - b;
}
int mul(int a, int b) {
	return a * b;
}
int Div(int a, int b) {//不考虑b=0的情况
	return a / b;
}
int main() {
	int a = 4;
	int b = 2;
	int(*p[4])(int a, int b) = { add,sub,mul,Div };
	for (int i = 0; i < 4; ++i) {
		printf("%d\n", p[i](a, b));
	}
	system("pause");
	return 0;
}

在这里插入图片描述
这里我们定义了一个函数指针数组p

int(*p[4])(int a, int b) = { add,sub,mul,Div };

此时函数指针数组如下图所示:
在这里插入图片描述
通过遍历函数指针数组来找到这四个函数的地址 , 再调用它们 , 这就是转移表的用法

2).指向函数指针数组的指针(函数指针数组指针)

指向函数指针数组的指针(函数指针数组指针) : 它是一个指针 , 一个数组指针 , 这个数组是函数指针数组 .
概念的层层嵌套让这个概念比较晦涩 , 而且绕口 ,
怎么申明它呢?
举个例子, 我们就申明pp, 如果pp要指向函数指针数组p (p的定义为int(*p[4])(int a, int b)), 那么我们就申明pp如下 :

	int(*(*pp)[4])(int a, int b) ;

需要注意的是指针pp[ ]内的值必须要和p[ ]内的的值相同
我们还是通过代码来看一下指向函数指针数组的指针(函数指针数组指针)的用法

#include<stdio.h>
#include<stdlib.h>
int add(int a, int b) {
	return a + b;
}
int sub(int a, int b) {
	return a - b;
}
int mul(int a, int b) {
	return a * b;
}
int Div(int a, int b) {//不考虑b=0的情况
	return a / b;
}
int main() {
	int a = 4;
	int b = 2;
	int(*p[4])(int a, int b) = { add,sub,mul,Div };
	int(*(*pp)[4])(int a, int b);
	pp = &p;
	//int(*(*pp)[4])(int a, int b) = &p;
	for (int i = 0; i < 4; ++i) {
		printf("%d\n", p[i](a, b));
	}
	printf("通过指向函数指针数组的指针调用\n");
	for (int i = 0; i < 4; ++i) {
		printf("%d\n", (*(*pp + i))(a, b));
		//等价printf("%d\n", (*(*pp)[i])(a, b));
	}
	system("pause");
	return 0;
}

在这里插入图片描述
其实这段代码

printf("%d\n", (*(*pp + i))(a, b));
//等价printf("%d\n", (*(*pp)[i])(a, b));

看似复杂 , 实则与数组指针的用法一样 , 只是这个数组指针中的"数组"变成了"函数指针数组" .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值