1. 程式人生 > 其它 >void型別應用 && 函式指標實現面向物件

void型別應用 && 函式指標實現面向物件

技術標籤:C語言基礎練習

原帖:

【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;
}