(一)前文回顾
1、前篇代码分析
void(*signal(int , void(*)(int)))(int) ;
那么这串代码究竟是什么呢?
别慌,让我们来一步一步拆解,首先我们通过之前的学习,已经明白了什么是函数指针(如果有不太懂得,请看前一篇文章)
仔细观察这串代码,不难发现出现了 signal 此时肯定会有人想是不是有什么特殊的含义。。。
很明显,signal就是简简单单的一个函数名,不行,来我们轻轻的把这串代码“大卸八块”。
(1)去掉最外层的 void()(int) 剩余 *signal(int , void(*)(int)) ; 现在signal只有两种可能。【1,就是指针 2,是函数名】
我们之前的学习中已经知道当 * 和()同时存在的时候,()首先于变量名结合,所以此处的 signal(int , void(*)(int)) 首先是一部分,也就是个函数。
(2)再来看 signal(int , void(*)(int)) 的()内的部分,我们发现有个 int,这说明函数内有个参数是 int 类型,那么剩余的参数 void(*)(int) 是什么类型呢?
学过函数指针的朋友不难看出,这就是一个函数指针类型的参数。
(3)再想想,* 是什么呢 ?此时发现不好解释啊,但是你把刚开始去掉的外层结构加上再看就会一目了然!
void(* )(int) //这也是个函数指针类型,再结合中间部分是个函数,我们就能明白整个代码 void(*signal(int , void(*)(int)))(int) ; 的意思是 函数指针类型的函数
(二)函数指针数组
1、基本知识
(1)本质:
函数指针数组,顾名思义就是存放函数指针的一个数组!!!
(2)示例
int add(int x , int y) //定义一个函数实现两个整数的相加
{
return x+y;
}int sub(int x , int y) //定义一个函数实现两个整数的相减
{
return x+y;
}int main()
{
int(*pf)( int ,int ) = add ; //定义一个函数指针指向 add 函数int(*pf1)( int ,int ) = sub ; //定义一个函数指针指向 sub 函数
int( *parr[2] )( int ,int ) = {pf,pf1 }; //此时的parr就是一个数组,类型为函数指针,存放了两个函数指针
}
根据上述代码,我们就能知道函数指针数组究竟是什么样的了,需要注意的是 函数指针数组和普通数组大致相同,存放的元素类型要相同,所以存放的函数指针的类型也要相同!!
2、练习——计算器——避免使用switch()
(1)基本思路
1. 首先简单的计算器我们需要 四个函数 来分别实现 加减乘除 四个功能 ;
2.需要一个菜单来提醒用户;
3.在主函数中需要循环,并且由于不使用 switch(),所以应用本节学习,使用函数指针数组。
(2)代码如下:
#include<stdio.h>
int Add(int x, int y) //定义四个函数
{return x + y;
}
int Sub(int x, int y)
{return x - y;
}
int Mul(int x, int y)
{return x * y;
}
int Div(int x, int y)
{return x / y;
}
void menu() //菜单
{printf("***0.加法*******\n");printf("***1.减法*******\n");printf("***2.乘法*******\n");printf("***3.除法*******\n");printf("***4.退出*******\n");
}
int main()
{int(*pf[5])(int, int) = { Add, Sub ,Mul,Div,NULL };//定义一个函数指针数组,数组第1,2//3,4个元素分别对应四个函数,可以使用下标来取出,最后一个元素是个空指针,来退出程序int a = 0; //定义一个局部变量来让用户选择具体算法int b, c = 0;do {//使用do while()循环可以不判断先执行一次menu();printf("请选择\n");scanf_s("%d", &a);if (a >= 0 && a <= 3)//下标在0~3即对应四个函数{printf("请输入两个数\n");scanf_s("%d %d", &b, &c);int ret = pf[a](b, c); //调用printf("%d\n", ret);}else if (a == 4)//下标为4就对应空指针{printf("退出\n");break;}else{printf("选择错误\n");//选择其余显示错误break;}} while (a);return 0;
}
执行如下: