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

    xiaoxiao2022-07-03  115

    对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));

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

    最新回复(0)