一步步理解typedef

1.如何用C語言實現一個函數,傳遞兩個整形數,返回兩個數的和?html

#include<stdio.h>

int add(int a,int b)
{
    return a+b;
}

void main()
{
    int a=1,b=2;
    printf("a=%d\nb=%d\nResult=%d",a,b,add(a,b));
    getchar();
}

2.同時計算兩個數的和與差?node

#include<stdio.h>

int add(int a,int b)
{
    return a+b;
}

int sub(int a,int b)
{
    return a-b;
}

void main()
{
    int a=1,b=2;
    printf("a=%d\nb=%d\na+b=%d\n\n",a,b,add(a,b));
    printf("a=%d\nb=%d\na-b=%d\n\n",a,b,sub(a,b));
    getchar();
}

  如今你所寫軟件已經具有加法和減法功能。要知道,人的慾望無窮無盡……函數

3.提供一個函數,使得我在加法完成以後作一些事情(必需要在函數加法函數返回以前作),好比打印結果,修改結果。 spa

#include <stdio.h>

int add(int a,int b)
{
    return a+b;
}

//提供一個能夠在add以後隨意作點事情的函數
//爲了修改值,因此須要傳遞變量的指針
//函數傳遞了一個函數指針,其原型爲:int (*)(int *)
int addAfterDoSomething(int a,int b,int (*AddAfter)(int *result))
{
    int resutl = add(a,b);
    AddAfter(&resutl);
    return resutl;
}

//要在add以後修改其值
int changeValue(int * value)
{
    printf("Value Before Change : %d\n",*value);
    *value = *value -1;
    printf("Value After Change : %d\n",*value);
}

void main()
{
    int a=1,b=2;
    printf("a=%d\nb=%d\nResult=%d",a,b,addAfterDoSomething(a,b,changeValue));
    getchar();
}

 

 4.提供一個函數,使得我在加法完成以後作一些事情(必需要在函數加法函數返回以前作)以後,再作一些事情。翻譯

//是的正如你所想,局勢在函數最後面再加一個函數指針
int addAfterDoSomething(int a,int b,int (*AddAfter)(int *result),int (*AddAfterAfter)(int *result))

5.提供一個函數,使得我在加法完成以後作一些事情(必需要在函數加法函數返回以前作)以後,再作一些事情以後,再作一些事情。指針

int addAfterDoSomething(int a,int b,int (*AddAfter)(int *result),int (*AddAfterAfter)(int *result),int (*AddAfterAfterAfter)(int *result))

  正如你所看,對於一個追求完美的人,上面黃色背景的那一串函數原型,太礙眼,太醜陋,看起來太複雜,太讓人接受不了。code

6.美化第3步的代碼htm

//省略若干

#ifndef DoSomethingAfterAdd
#define DoSomethingAfterAdd int (*AddAfter)(int *result)
#endif 

//省略若干
//
int addAfterDoSomething(int a,int b,int (*AddAfter)(int *result))
//替換爲
int addAfterDoSomething(int a,int b,DoSomethingAfterAdd);

7.美化第四步的代碼blog

//省略若干

#ifndef DoSomethingAfterAdd
#define DoSomethingAfterAdd int (*AddAfter)(int *result)
#endif 

//省略若干
//
int addAfterDoSomething(int a,int b,int (*AddAfter)(int *result))
//替換爲 
int addAfterDoSomething(int a,int b,DoSomethingAfterAdd,DoSomethingAfterAdd);  
//很明顯,這樣通不過編譯!
//Error:重複的參數名

 正確的方法以下:get

//定義一個帶有參數的宏
#ifndef DoAfter(X)
#define DoAfter(X) int (*X)(int *result) #endif

//在編譯代碼時,編譯器會將DoAfter(AddAfter)翻譯爲int (*AddAfter)(int *result)
//同理,DoAfter(AddAfterAfter) ==int (*AddAfterAfter)(int *result)
int addAfterDoSomething(int a,int b,DoAfter(AddAfter),DoAfter(AddAfterAfter));

   參考:https://gcc.gnu.org/onlinedocs/cpp/Macro-Arguments.html

8.美化第5步

//固然很是簡單了……
int addAfterDoSomething(int a,int b,DoAfter(AddAfter),DoAfter(AddAfterAfter),DoAfter(AddAfterAfterAfter))
{
    int resutl = add(a,b);
    AddAfter(&resutl);
    AddAfterAfter(&resutl);
    AddAfterAfterAfter(&resutl);
    return resutl;
}

 9.美化第八步

//定義一個自定義類型FunAddAfter
//類型的值爲一個指向函數的指針
typedef int(* FunAddAfter)(int *Result);

//能夠像使用int類型同樣使用FunAddAfter
int addAfterDoSomething(int a,int b,FunAddAfter AddAfter,FunAddAfter AddAfterAfter,FunAddAfter AddAfterAfterAfter)
{
    int resutl = add(a,b);
    AddAfter(&resutl);
    AddAfterAfter(&resutl);
    AddAfterAfterAfter(&resutl);
    return resutl;
}

void main()
{
    int a=1,b=2;
    //在使用自定義類型時,須要像其餘類型同樣聲明,賦值,而後使用   -.-廢話
    FunAddAfter change;
    //函數名其實也就是一個指針,指向函數的地址 
  change
= changeValue; printf("a=%d\nb=%d\nResult=%d",a,b,addAfterDoSomething(a,b,change)); getchar(); }

  到這裏若是說teypdef的做用也就是美化的話,那麼#define徹底能夠勝任全部的工做。

10.實現一個函數,使得能夠在加法運算後執行若干個,未知個數個其餘事情  

/定義一個自定義類型FunAddAfter
//類型的值爲一個指向函數的指針
typedef int(* FunAddAfter)(int *Result);

typedef struct _funList
{
    FunAddAfter node;
    struct _funList * nextNode;
} FunList,*PFunList;

//僅僅打印值
int printfValue(int * value)
{
    printf("the Value is :%d\n",*value);
    return *value;
}

//計算一個數的平方
int Squre(int * value)
{    
    printf("Squre value :%d is %d\n",*value,(*value)*(*value));
    return *value=(*value)*(*value);;
}


int DoManythingAfterAdd(int a, int b ,PFunList funlist)
{
    int result = add(a,b);
    while (NULL!=funlist)
    {
        result = funlist->node(&result);
        funlist = funlist->nextNode;
    }
    return result;
}

void main()
{
    int a=1,b=2;
    //在使用自定義類型時,須要像其餘類型同樣聲明,賦值,而後使用   -.-廢話
    FunAddAfter change,squreValue,printvalue;
    PFunList funlistHead,funListNode1,funListNode2;
     //函數名其實也就是一個指針,指向函數的地址
    change = changeValue;
    squreValue=Squre;
    printvalue = printfValue;    
    funlistHead =(FunList *) malloc(sizeof(FunList));
    funListNode1 =(FunList *) malloc(sizeof(FunList));
    funListNode2 =(FunList *) malloc(sizeof(FunList));
    funlistHead->nextNode = funListNode1;
    funlistHead->node = change;
    funListNode1->nextNode = funListNode2;
    funListNode1 ->node = printvalue;
    funListNode2 ->node = squreValue;
    funListNode2 ->nextNode = NULL;
    printf("a=%d\nb=%d\nResult=%d",a,b,DoManythingAfterAdd(a,b,funlistHead));
    getchar();
}

 

 總結typedef的做用

1.知足Geek的簡潔代碼需求——正如你所看到的,函數的功能其實也能夠經過一長串的函數原型來實現,或者使用宏定義,我也能夠不使用typedef來完成功能,可是對於追求卓越的人,容忍不了看起來太長和複雜的函數定義

2.知足Geek的控制慾——除了C標準提供的基本類型,我也要定義一個本身的公司內部使用的類型,在公司不得使用int,而必定要使用tianchaoweida

typedef int tianchaoweida;

3.由於tepedef能定義自定義類型,因此就可以超越#Define,有本身獨特存在的理由!以下:

FunAddAfter change,squreValue,printvalue;

 

源碼下載

相關文章
相關標籤/搜索