一亩三分地

一份辛勤,一份收获,愿与大家共享,互相勉励!

   :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

为什么我们在C程序中定义结构时经常要用到typedef呢?如:
typedef struct tagStudentMsg {
   int m_iStudentNum;
   char m_szName[64];
} StudentMsg;

你知道这是什么语法吗?让我细细说来:首先,它声明了一个结构体,struct tagStudentMsg;然后使用typedef为这个结构体声明了一个别名。这样,当要定义一个这样类型的变量时,只需要如此写:StudentMsg Stud1;否则,需要如此:struct tagStudentMsg Stud1。简便了不少。在这个例子中,tagStudentMsg是结构标签,而StudentMsg是用typedef声明的结构类型。

  如果上例写成这样的话:

struct tagStudentMsg {
   int m_iStudentNum;
   char m_szName[64];
} StudentMsg;

  那么StudentMsg的意义将和第一例中的完全不同,此处StudentMsg只是一个类型为struct tagStudentMsg的变量,是无法用来定义其他变量的。

  一般情况下,typedef用于简结地表示指向其他东西的指针。典型的例子是signal()原型的声明。signal()是一种系统调用,用于通知运行时系统,当某种特定的“软件中断“发生时调用特定的程序。调用signal(),通过参数传递告诉它中断的类型以及用于处理中断的程序。在ANSI C标准中,signal的声明如下:

  void (*signal(int sig, void(*func)(int)))(int);

  上例很艰涩,经过仔细分析方可得出结论:signal是一个函数,它返回一个函数指针,该指针所指向的函数接受一个int参数并返回void。signal函数有两个参数,一个是int sig,用来表示信号类型,还有一个是void (*func)(int),不难看出,它是一个函数指针,所指向的函数接受一个int参数,返回值是void。可以看到,它和signal返回的函数指针类型其实是一样的。那么,我们用typedef代表通用部分,从而进行简化:

  typedef void (*ptr_to_func)(int);

      ptr_to_func signal(int, ptr_to_func);

  如此一来,signal()的声明就一目了然了。

  任何一件事物都是有其两面性的,实际上在《C专家编程》中,对typedef的使用并不广泛推荐:它同样具有与其他声明一样的混乱语法,同样可以把几个声明器塞到一个声明中去。对于结构,除了可以在书写时省掉struct关键字之外,typedef并不能提供显著的好处,而少写一个struct其实并没有多大帮助。在任何typedef声明中,甚至不必把typedef放在声明的开始位置。

  它还提供了一个便贴提醒读者:

  • 不要为了方便起见对结构使用typedef
这样做的唯一好处是使你不必书写”struct“关键字,但这个关键字可以向你提示一些信息,你不应该把它省掉。
  • typedef应该用在
    • 数组、结构、指针以及函数的组合类型。
    • 可移植类型。比如当你需要一种至少20bit的类型时,可以对它进行typedef操作 typedef的提示声明。这样,当代码移植到不同的平台时,要选择正确的类型如short, int, long时,只要在typedef中进行修改就可以了,无需对每个声明都加以修改。
    • typedef也可以为后面的强制类型转换提供一个简单的名字。
    • 应该始终在结构的定义中使用结构标签,即使它并非必须,这种做法可以使代码更为清晰。
posted on 2014-03-29 23:30  斯米戈l  阅读(306)  评论(0编辑  收藏  举报