C专家编程 六 typedef

        typedef是一种有趣的声明形式:它为一种类型引入新的名字,而不是为变量分配空间。 在某些方面,typedef类似于宏文本替换——它并没有引入新类型,而是为现有类型取个新名 字,但它们之间存在一个关键性的区别,容我稍后解释。
        如果现在回过头去看看“声明是如何形成的”那一节,会发现typedef关键字可以是一个 常规声明的一部分,可以出现在靠近声明开始部分的任何地方。事实上,typedef的格式与变 量声明完全一样,只是多了这个关键字,向你提醒它的实质。
        由于typedef看上去跟变量声明完全一样,它们读起来也是一样的。前面•节描述的分析 技巧也同样适用于typedef。普通的声明表示“这个名字是一个指定类型的变量”,而typedef 关键字并不创建一个变量,而是宣称“这个名字是指定类型的同义词”。

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

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

让我们运用刚刚掌提的技巧来分析这个声明,会发现它的意思如下:

void(*signal( ))(int);

        signal是一个函数(具有一些令人胆战心惊的参数),它返回一个函数指针,后者所指向 的函数接受一个int参数并返回void。其中一个恐怖的参数是其本身:

void(*func> (int);

        它表示一个函数指针,所指向的函数接受一个int参数,返回值是void。现在,让我们 看一下怎样用typedef来“代表”通用部分,从而进行简化。

typedef void (*pt3:_to_func) (int);

/*它表示ptr_to_func是一个函数指针,该函数 *接受一个int参数,返回值为void。*/

ptr_to—func signal (int, ptr—to—func:);

/*它表不signal是一个函数,它接受两个参数,

*其中一个是int,另一个是ptr_to_func,返回 * 值是 ptr_to_func。

*/

         然而,说到typedef就不能不说一下它的缺点。它同样具有与其他声明一样的混乱语法,同样可以把几个声明器塞到一个声明中去。对于结构,除了可以在书写时省掉Struct关键字 之外,typedef并不能提供显著的好处,而少写一个struct其实并没有多大帮助。在任何typedef 声明中,甚至不必把typedef放在声明的开始位置。

操作声明器的一些提示

不要在一个typedef中放入几个声明器,如下所示:

typedef int *ptr/ (fun)(), arr[5];

/* ptr是“指向int的指针”类型,

* fun是“指向返回值为int的函数的指针”类型

* arr是“长度为5的int型数组”类型 */

千万不要把typedef嵌到声明的中间部分,如下所示:

unsigned const long typedef int volatile *kumquat;

typedef为数据类型创趕别名,而不是创建新的数据类型,可以对任何类型进行typedef声明。

typedef int (*array_ptr)[100];

        应该只对所希望的变量类型进行typedef声明,为变量类型取一个喜欢的别名。关键字 typedef应该如前所述出现在声明的开始位置。在同一个代码块中,typedef引入的名字不能与 其他标识符同名。

typedef int x[10]和#define x init[10]的区别

         前面已经提到过,在typedef和宏文本替换之间存在一个关键性的区别。正确思考这个问 题的方法就是把typedef看成是一种彻底的“封装”类型——在声明它之后不能再往里面增加 别的东西。它和宏的区别体现在两个方面。
        首先,可以用其他类型说明符对宏类型名进行扩展,但对typedef所定义的类型名却不能 这样做。如下所示:

unsigned const long typedef int volatile *kumquat;

声明。

typedef int (*array_ptr)[100];

#define peach int unsigned peach i ; /* 没问

typedef int banana;

unsigned banana i; /* 错误! 非法 */

       其次,在连续几个变量的声明中,用typedef定义的类型能够保证声明中所有的变S均为 同一种类型,而用#define定义的类型则无法保证。如下所示:

#define int_ptr int * int_ptr chalk, cheese;

经过宏扩展,第二行变为:

int * chalk, cheese;

        这使得chalk和cheese成为不同的类型,就好象是辣椒酱与细香葱的区别:chalk足个 指向int的指针,而cheese则是一个int。相反,下面的代码中:

typedef char * char_ptr; char_ptr Bentley, Rolls_Royce;

Bentley和RollS_Royce的类型依然相同。虽然前面的类型名变了,但它们的类型相同, 都是指向char的指针。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值