typedef用法


在很多中文(包含翻译过来的中文)C语言书籍,对typedef含义总结性的一句话就是,重新定义一种数据类型(或者是给类型起别名)。在之前很长的一段时间里,我并不理解它的用法,甚至觉得它没有#define好。

比如我想简写unsigned char,我觉得用#define uchar unsigned char就挺方便的,后来随着应用越来越复杂,我才感觉到typedef的好处,也慢慢理解它与#define的区别。我们举以下几种情况来讨论#define与typedef的区别与用法。

1、宏替换,肯定只能用#define了,比如:#define PI 3.14

2、给简单数据类型起别名:#define uint32 unsigned int  或   typedef unsigned int uint32;其实这两个是一样的。

3、声明一个指向简单数据类型变量的指针,比如我们这样定义  #define uint32_p   unsigned int *  如果我们只用来声明一个指针变量是没问题的,但是要是出现这样一种情况:uint32_p  p1,p2;结果会怎样呢?根据#define替换的功能,可以解析成

unsigned int *p1,p2;而这个声明的作用与我们之前的目的是完全不一样了吧。而如果我们换成了typedef unsigned int * uint32_p;uint32_p,是一种新的数据类型,完全可以用它去声明uint32_p p1,p2;

4、结构体类型的声明:typedef struct{

                   uint32 a;

                   uint16 *p;

                  uint16 array[10];

                                                           }m_T;        我们可以直接用m_T声明结构体变量;m_T  m1,*m2;而且我们可以把这个声明放在一个头文件里,方便其它想使用这个声明的地方。这里要是换成用#define实现会怎样呢?我是没试过......

5、我们看这样一个表达式,也是学习指针(函数指针、指针函数)最为经典的例子:(*(void (*)())0)();我们知道void(*)()这是一个函数指针类型的声明,声明了一个指向返回值类型为void的函数的函数指针,函数指针指向的函数的地址为0地址,最后(*0)();调用内存地址为0的那个函数,假如我们在程序的其它地方也会用到void (*)(),我们是不是考虑一下,用typedef  void (*A)()当我们再要定义返回值类型为void类型的函数指针时只用写:A a;,那么最开始的例子就可以写作:(*(A)0)();其实这里如果换成#define void (*)() A,是不会也能实现这个效果呢?

写到这里我要借助C陷阱与缺陷里的内容了,请大家自己理解:

使用 typedef 的目的 or 好处:

1、为了使表达式更简洁,上面的这个例子:(*(void(*)())0)();假如程序里很多地方要用到类型: void(*)() ,我们可以为这种类型起一个别名:typedef void (*A)();,当我们再要定义返回值类型为void类型的函数指针时只用写:A a;,那么最开始的例子就可以写作:(*(A)0)();
2、为了隐藏特定类型的实现,强调类型的使用目的
3、允许一种类型用于多个目的,同时使得每次使用给类型的目的明确
如:typedef int (*Function)(const char *, const char *);

该定义表示 Function 是一种指向函数的指针的类型的别名,要使用这种指针类型时只需直接使用 Function即可,不必每次把整个声明都写出来

void (*Signal(int,void(*)(int)))(int);

typedef void (*HANDLER)(int);

HANDLER Signal(int,HANDLER);
上下两种声明意义是一致的


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM