// 从别人那转的,调整下格式便于阅读。

首先请看看下面这两句:

typedef int a[];

typedef void (*p)(void); 

如果你能一眼就看出它们的意思,那请不要再往下看了。如果你不太理解,或概念还有些模糊,请继续往下看吧。

typedef用来声明一个别名,typedef后面的语法,是一个声明。本来这里不会产生什么误解的,但结果却出乎意料,产生误解的人不在少数。罪魁祸首又是那些害人的教材。在这些教材中介绍typedef的时候通常会写出如下形式:

typedef int PARA;

这种形式跟#define int PARA几乎一样!这些教材的宗旨是由浅入深,但实际做出来的行为却是以偏盖全!

的确,这种形式在所有形式中是最简单的,但却没有对 typedef进一步解释,使得不少人用#define的思维来看待typedef,把int与PARA分开来看,int是一部分,PARA是另一部分,但实际上根本就不是这么一回事。int与PARA是一个整体!就象int i:声明一样是一个整体声明,只不过int i定义了一个变量,而typedef定义了一个别名。

由于持有这种错误的观念,就会无法理解如下一些声明:

typedef int a[];
typedef void (*p)(void);

会以为a[10]是int的别名,(*p)(void)是void的别名,但这样的别名看起来又似乎不是合法的名字,于是陷入困惑之中。实际上,上面的语句把a声明为具有10个int元素的数组的类型别名,p是一种函数指针的类型别名。

虽然在功能上,typedef可以看作一个跟int PARA分离的动作,但语法上typedef属于存储类声明说明符,因此严格来说,typedef int PARA整个是一个完整的声明。

定义一个函数指针类型。比如原函数是:

void func(void);

那么定义的函数指针类型就是:

typedef void (*Fun)(void);

然后用此类型生成一个指向函数的指针:

Fun func1;

当func1获取函数地址之后,那么你就可以向调用原函数那样来使用这个函数指针:func1(void);

下面是理解typedef的正确方法,分为以下几步:

1. 确定被声明的类型:遇到typedef时,从左到右进行扫描,找到第一个“陌生”的标志符,这个标志符就应该是语句所声明的类型名称。例如: typedef int* (* pt)(int* (*pn)(int * p1,int *p2),int * p3); 如果pt是生词(既不是保留字,也不是生命过的类型),那么它就是要声明的类型。其它的名字都是为了阅读方便的占位符,可有可无。也就是说,上面的语句等价为: typedef int * (*pt)(int * (*)(int *, int *),int *);

2. 之后一旦遇到该类型声明的变量,则在该类型的typedef式中用变量代替类型,去掉typedef关键字,所得到的声明式等价与原来的声明。例如: pt p; 这个声明式,可以经过两步变化为等价的声明式。

首先,回到pt的typedef式: typedef int * (*pt)(int * (*)(int *, int *),int *); 用p代替pt: typedef int * (*p)(int * (*)(int *, int *),int *); 然后把typedef去掉,得到: int * (*p)(int * (*)(int *, int *),int *); 这个语句与 pt p;意义相同。

如果基础扎实,应该知道,这是个函数指针的声明,所指向的函数有两个int * 参数,返回一个int *值,第二个参数是int * ,整个函数返回一个int *。

typedef和define的区别

typedef和define都可以用来给对象取一个别名,但是两者却有着很大不同。

1. 首先,二者执行时间不同 关键字typedef在编译阶段有效,由于是在编译阶段,因此typedef有类型检查的功能。 Define则是宏定义,发生在预处理阶段,也就是编译之前,它只进行简单而机械的字符串替换,而不进行任何检查。
#define用法例子:

#define f(x) x*x
main( )
{
int a=,b=,c;  
c=f(a) / f(b);  
printf("%d //n",c);
}

程序的输出结果是: 36,根本原因就在于#define只是简单的字符串替换。

2. 功能不同 Typedef用来定义类型的别名,这些类型不只包含内部类型(int,char等),还包括自定义类型(如struct),可以起到使类型易于记忆的功能。 如:

typedef int (*PF) (const char *, const char *); 

定义一个指向函数的指针的数据类型PF,其中函数返回值为int,参数为const char *。

typedef 有另外一个重要的用途,那就是定义机器无关的类型,例如,你可以定义一个叫 REAL 的浮点类型,在目标机器上它可以i获得最高的精度:

typedef long double REAL; 在不支持 long double 的机器上,该 typedef 看起来会是下面这样:

typedef double REAL; 并且,在连 double 都不支持的机器上,该 typedef 看起来会是这样:

typedef float REAL;
#define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。
3. 作用域不同 #define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用。 而typedef有自己的作用域。

void fun()
{
#define A int
}
void gun()
{
//在这里也可以使用A,因为宏替换没有作用域,
//但如果上面用的是typedef,那这里就不能用A ,不过一般不在函数内使typedef
}

4. 对指针的操作 二者修饰指针类型时,作用不同。

typedef int *pint;
#define PINT int * const pint p;//p不可更改,p指向的内容可以更改,相当于int * const p;
const PINT p;//p可以更改,p指向的内容不能更改,相当于 const int *p; 或 int const *p; pint s1, s2; //s1和s2都是int型指针
PINT s3, s4; //相当于int * s3,s4;只有一个是指针

最新文章

  1. 移除HTML5 input在type="number"时的上下小箭头
  2. Django web 进阶
  3. tcp_tw_recycle 的问题, 使用某一个wifi,APP老是连接不上网络
  4. android应用程序如何调用支付宝接口(转)
  5. 【BZOJ】【2424】【HAOI2010】订货
  6. css-实现元素垂直居中对齐
  7. 转自 Because of you 的总结
  8. MySQL 创建库
  9. Android 自定义下拉刷新ListView
  10. MYSQL - php 使用 localhost 无法连接数据库
  11. mac系统如何处理来自身份不明的开发者
  12. RocketMQ消费批拉超过32不生效
  13. Luogu5245 【模板】多项式快速幂(多项式exp)
  14. 小甲鱼Python第十二讲课后习题---013元组
  15. Extjs Window用法详解 2 打印具体应用
  16. swiper3d横向滚动多张炫酷切换banner
  17. Python学习之文件操作
  18. ES6-const注意
  19. js的组合函数
  20. sublime中开启表格插入

热门文章

  1. 【u242】排名系统
  2. C#连接Sqlserver代码
  3. Linux环境编写脚本安装配置JDK,Tomcat,含Tomcat自启动
  4. iOS6 与iOS7以及7以上状态栏的颜色设置
  5. .NET开发人员的瓶颈和职业发展
  6. python 快速排序 完整
  7. 3 学习UML图 学习DDD的基本概念
  8. 使用c++代替使用的c包!
  9. C# TSF 输入法的获取
  10. vc有关 directx组态,和dxsdk_extras(directshow)