一、代码部分
#include<stdio.h>
/*
int add(int ,int);
int sub(int ,int);
int mul(int ,int);
int dil(int ,int);
*/
//加减乘除的具体实现
int add(int first,int second){
return first + second;
}
int sub(int first,int second){
return first - second;
}
int mul(int first,int second){
return first * second;
}
int dil(int first,int second){
if(second == 0){
printf("ERROR!!\n");
return 0;
}
return first / second;
}
int main(int arc,char **argv){
int first = 0;
int second = 0;
char opr = 0;
//'+','-','*','/'对应的ASC2码分别是43 45 42 47
int (*op[])(int ,int) = {&mul,&add,NULL,&sub,NULL,&dil};
//这里需要解释下 int (*op[])(int,int)
//op是指向 需要两个int型参数的返回值是int类型的函数 的指针 的数组
printf("please input(num operate num)>>>");
scanf("%d %c %d",&first,&opr,&second);//输入格式是 “第一个整数 操作符 第二个整数” 中间有空格
//没做数组越界判断,所以输错格式程序会出错
printf("result>>>%d\n",op[opr-42](first,second));
return 0;
}
二、函数指针解释
函数指针就是指向函数的指针,简答的声明方式:type (*function)(type parameter)
要理解类似的指针函数等混合在一起的声明并不困难,只要把握了 操作符优先级 和 操作符结合性,然后从里向外分析就好,
例如:一个最基本的例子int *fun(int);
首先,我们要高清楚我们要做的是分析工作是什么:分析fun是什么,注意是fun是什么,二不是fun()是什么,这是有差别的;
其次,从里向外看,最里层是fun,我们探求的目标,然后外面一层是()和*,显然()结合性是最高的,所以我们得到了一个fun(int),它是什么呢?它就是它左边剩下的int*,他们是等价的(或者应该说fun()将会返回一个int类型指针);
然后,我们在一fun(int)为基础再往外层看,得到*fun(int),它就是左边的int;
所以从int *fun(int)我们可以分析出,fun是需要一个int型参数,它的返回值是一个指向int型的指针
这时在看int (*fun)(int)就很明了了
fun它的左边是*,所以它是一个指针
(*fun)它右边(int)优先级最高,所以(*fun)是一个函数,它需要一个int型参数
(*fun)(int)它左边是一个int,所以(*fun)(int)是一个int型
所以fun就是指向返回值是int 需要一个int型参数的函数 的指针。
数组指针,指针数组什么的其实也是一个道理,例如:
int* arr[],因为[]优先级比*高,所以arr是一个指针数组(一个装了很多int型指针的数组)
再看int(*arr)[],arr就是指向int型数组的指针了
最麻烦的应该就是数组指针函数混合起来了,例如上面代码中的int (*op[])(int ,int)
op旁边[]优先级最高,所以op是一个数组;
op[]在旁边是*,所以op[]是一个指针;
*op[]旁边(int,int)结合型最高,所以(*op[])是一个函数;
最后剩下的是最左边的int,即(*op[])(int ,int)返回值为int;
所以op是什么就不说了,你懂得。
说到这里上面在看上面的代码就很简单了,其实就是构造了一个函数指针数组,然后在使用不同的操作时调用用相应的函数而已。
其实,MFC的消息转发机制也是使用了这种思想
下面简单看一个一个简单的MFC单文档工程的消息转发表是如何建立的(我建立的工程命为test):
CMFCtestApp头文件中有一行宏DECLARE_MESSAGE_MAP(),它就是消息转发表的声明,右键跳至定义:
#define DECLARE_MESSAGE_MAP() \
private: \
static const AFX_MSGMAP_ENTRY _messageEntries[]; \
protected: \
static AFX_DATA const AFX_MSGMAP messageMap; \
virtual const AFX_MSGMAP* GetMessageMap() const; \
可以看到它声明了一个AFX_MSGMAP_ENTRY 数组_messageEntries,其实这就是那个转发表,AFX_MSGMAP_ENTRY是一个结构体:
struct AFX_MSGMAP_ENTRY
{
UINT nMessage; // windows message
UINT nCode; // control code or WM_NOTIFY code
UINT nID; // control ID (or 0 for windows messages)
UINT nLastID; // used for entries specifying a range of control id's
UINT nSig; // signature type (action) or pointer to message #
AFX_PMSG pfn; // routine to call (or special value)
};
可以看到它包含了一些消息类型nMessage、ID等数据,最后一行就是nMessage对应消息的处理函数,MFC就是通过类中的这个消息映射表实现的消息转发,其实也就是个函数指针的使用。
weibo.com/TMDJoJo