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\nb=%d\nResult=%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\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.提供一个函数,使得我在加法完成之后做一些事情(必须要在函数加法函数返回之前做),比如打印结果,修改结果。
#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))
正如你所看,对于一个追求完美的人,上面黄色背景的那一串函数原型,太碍眼,太丑陋,看起来太复杂,太让人接受不了。
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\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;