zoukankan      html  css  js  c++  java
  • typedef

    http://baike.baidu.com/view/1283800.htm?fr=aladdin

    百度解释

    进阶版本  转

    一步步理解typedef

     

    1.如何用C语言实现一个函数,传递两个整形数,返回两个数的和?

    复制代码
    #include<stdio.h>
    
    int add(int a,int b)
    {
        return a+b;
    }
    
    void main()
    {
        int a=1,b=2;
        printf("a=%d
    b=%d
    Result=%d",a,b,add(a,b));
        getchar();
    }
    复制代码

    2.同时计算两个数的和与差?

    复制代码
    #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
    b=%d
    a+b=%d
    
    ",a,b,add(a,b));
        printf("a=%d
    b=%d
    a-b=%d
    
    ",a,b,sub(a,b));
        getchar();
    }
    复制代码

      现在你所写软件已经具备加法和减法功能。要知道,人的欲望无穷无尽……

    3.提供一个函数,使得我在加法完成之后做一些事情(必须要在函数加法函数返回之前做),比如打印结果,修改结果。 

    复制代码
    #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
    ",*value);
        *value = *value -1;
        printf("Value After Change : %d
    ",*value);
    }
    
    void main()
    {
        int a=1,b=2;
        printf("a=%d
    b=%d
    Result=%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))

      正如你所看,对于一个追求完美的人,上面黄色背景的那一串函数原型,太碍眼,太丑陋,看起来太复杂,太让人接受不了。

    6.美化第3步的代码

    复制代码
    //省略若干
    
    #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.美化第四步的代码

    复制代码
    //省略若干
    
    #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:重复的参数名
    复制代码

     正确的方法如下:

    复制代码
    //定义一个带有参数的宏
    #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 b=%d Result=%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
    ",*value);
        return *value;
    }
    
    //计算一个数的平方
    int Squre(int * value)
    {    
        printf("Squre value :%d is %d
    ",*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
    b=%d
    Result=%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;
  • 相关阅读:
    实验吧之snake
    实验吧之Canon
    实验吧之紧急报文
    实验吧之deeeeeeaaaaaadbeeeeeeeeeef-200
    Centos Linux 使用Yum安装Go和配置环境
    harbor仓库搭建
    教你怎么半天搞定Docker
    教你分分钟搞定Docker私有仓库Registry
    kubernetes学习:CKA考试题
    Python基础知识
  • 原文地址:https://www.cnblogs.com/For-her/p/3796368.html
Copyright © 2011-2022 走看看