void类型应用 && 函数指针实现面向对象

原帖:

【C进阶】同事用void把我给秀翻了!

 

摘录:

 虽然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;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值