原帖:
摘录:
虽然void不能直接修饰变量,但是其可以用于修饰指针的指向即无类型指针void*,无类型指针那就有意义了,无类型指针不是一定要指向无类型数据,而是可以指向任意类型的数据。
使用函数指针实现面向对象:
在Oper()接口中,除了可以定义一个函数指针对象,还可以直接用:
方式1:(*((void (*)(void*))pfunc))(param);
方式2:((void (*)(void*))pfunc)(param);
如果上述不容易理解,可以直接定义函数指针变量实现,也未尝不可。毕竟实际工程中重要的是没bug,不以秀操作为目的
顿悟,其实很简单,上面的那个语句就是把定义函数指针和赋值合并到一个语句中了。拆分如下:
原式: (*((void (*)(void*))pfunc))(param);
分解式:
1- void (*) (void *) pfunc
相当于定义了一个函数指针变量,变量赋值为pfunc。等同于下面语句:
void (*pFunc)(void *); --分解1
pFunc = pfunc; --分解2
2- (*((void (*)(void*))pfunc))(param);
相当于执行函数,等同于
(*pFunc )(param) --分解3
其中:
原式中的void (*) 等于分解1中的void (*pFunc),表明定义了一个函数指针变量,函数的返回值为void
原式中的(void *)等于分解1中的(void *),表明函数入参为void *类型变量
原始中的pfunc等于分解2中的pFunc = pfunc,相当于把函数指针赋值给函数指针变量
原始中的param相当于分解3中的函数入参
注:
查阅《c和指针》发现在函数指针章节说明如下:
void (*pFunc)(void *); --分解1
pFunc = pfunc; --分解2-1
pFunc = &pfunc; --分解2-2
(*pFunc )(param) --分解3-1
pFunc(param) --分解3-2
上述的2-1和2-2以及3-1和3-2都是正确的,所以不必纠结下面哪种方式是正确的,都是对滴。
方式1:(*((void (*)(void*))pfunc))(param);
方式2:((void (*)(void*))pfunc)(param);
#include<stdio.h>
#include<stdlib.h> //exit()
#include<string.h>
/*计算结构体*/
typedef struct s_calculate{
int num1;
int num2;
int result;
}sCal;
/**********************************
*Func: Add
*Descript:加法计算
*Return: 无
**********************************/
void Add(void * param)
{
if(NULL == param)
{
printf("%s(%d) input is null\n",__func__, __LINE__);
return;
}
sCal *p_add = (sCal *)param;
p_add->result = p_add->num1 + p_add->num2;
}
/**********************************
*Func: Sub
*Descript:减法计算
*Return: 无
**********************************/
void Sub(void * param)
{
if(NULL == param)
{
printf("%s(%d) input is null\n",__func__, __LINE__);
return;
}
sCal *p_sub = (sCal *)param;
p_sub->result = p_sub->num1 - p_sub->num2;
}
/**********************************
*Func: Oper
*Descript:操作运算符函数
*Return: 无
**********************************/
void Oper(void * param, void *pfunc)
{
void (*pFunc)(void *);
if((NULL == param) || (NULL == pfunc))
{
printf("%s(%d) input is null\n",__func__, __LINE__);
return;
}
pFunc = pfunc;
(*pFunc)(param);
//(*((void (*)(void*))pfunc))(param);
//((void (*)(void*))pfunc)(param);
}
/**********************************
*Func: main
*Descript:函数入口
*Return: 无
**********************************/
int main()
{
sCal scal;
memset((void *)&scal, 0, sizeof(sCal));
scal.num1 = 5;
scal.num2 = 3;
Oper(&scal, Add);
printf("%d+%d = %d\n", scal.num1, scal.num2, scal.result);
Oper(&scal, Sub);
printf("%d-%d = %d\n", scal.num1, scal.num2, scal.result);
return 0;
}