码迷,mamicode.com
首页 > 其他好文 > 详细

一步步理解typedef

时间:2014-05-17 15:11:03      阅读:380      评论:0      收藏:0      [点我收藏+]

标签:style   blog   class   code   c   java   

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

bubuko.com,布布扣
#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();
}
bubuko.com,布布扣

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

bubuko.com,布布扣
#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();
}
bubuko.com,布布扣

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

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

bubuko.com,布布扣
#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();
}
bubuko.com,布布扣

 

 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步的代码

bubuko.com,布布扣
//省略若干

#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);
bubuko.com,布布扣

7.美化第四步的代码

bubuko.com,布布扣
//省略若干

#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:重复的参数名
bubuko.com,布布扣

 正确的方法如下:

bubuko.com,布布扣
//定义一个带有参数的宏
#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));
bubuko.com,布布扣

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

8.美化第5步

bubuko.com,布布扣
//当然非常简单了……
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;
}
bubuko.com,布布扣

 9.美化第八步

bubuko.com,布布扣
//定义一个自定义类型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(); }
bubuko.com,布布扣

  到这里如果说teypdef的作用也就是美化的话,那么#define完全可以胜任所有的工作。

10.实现一个函数,使得可以在加法运算后执行若干个,未知个数个其他事情  

bubuko.com,布布扣
/定义一个自定义类型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();
}
bubuko.com,布布扣

 

 总结typedef的作用

1.满足Geek的简洁代码需求——正如你所看到的,函数的功能其实也可以通过一长串的函数原型来实现,或者使用宏定义,我也可以不使用typedef来完成功能,但是对于追求卓越的人,容忍不了看起来太长和复杂的函数定义

2.满足Geek的控制欲——除了C标准提供的基本类型,我也要定义一个自己的公司内部使用的类型,在公司不得使用int,而一定要使用tianchaoweida

typedef int tianchaoweida;

3.因为tepedef能定义自定义类型,所以就能够超越#Define,有自己独特存在的理由!如下:

FunAddAfter change,squreValue,printvalue;

 

源码下载

一步步理解typedef,布布扣,bubuko.com

一步步理解typedef

标签:style   blog   class   code   c   java   

原文地址:http://www.cnblogs.com/pavkoo/p/3729363.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!