C语言中typedef之分析

以前自己对于C语言中的typedef理解非常简单:为一个类型取一个别名,因而它的语法应当是这样的形式:

typedef 类型 类型的别名

比如typedef int size_t这样的用法,size_t其实就是int换了个名字而已,稍微复杂一点的是和结构体结合在一起使用,不过也非常容易理解,我们知道声明一个结构体其实就是声明一个抽象数据类型,因此依然能够归结到上面的语法中去。直到某一天我在学习Advance Programming in the UNIX Environment 的时候看到了以下这行代码:

typedef int Myfunc(const char *, const struct stat *, int)

不禁大吃一惊,神码!居然给int取了个别名,这个别名是。。。是一个函数??!仔细一看发觉不对,int应当是属于Myfunc的,后面的式子连起来是一个完整的函数声明。结合后面的代码,大致猜出了这句的意思:声明了一个名为"Myfunc"的“函数类型”。用起来非常方便,可以用来声明函数,比如Myfunc myfunc这样的声明就相当于:int myfunc(const char *, const struct stat *, int),更妙的是可以用来简化函数指针,比如:myftw(char *pathname, Myfunc *func)。

于是乎意识到typedef不仅仅是取别名这么简单,其语法颇值得玩味,之前自己的理解是有偏差的(我认为typedef后面一定是有两个“参数”)。

关于typedef一个有意思的地方是和#define的差别,#define宏也可以用来取别名,#define的原理是很简单的,编译器做简单的文本替换,比如我们写#define int size_t的话,用到size_t的地方会被替换成int。查了一下资料,发现编译器中typedef的处理过程大致是这样的:typedef后面的部分是一个包含未知符号的一元表达式,编译器把声明表达式带入这个一元式,直至消除掉所有的未知符号为止。

以上的描述可能不是太准确,而且也非常抽象,下面举两个例子来说明:

对于typedef int size_t,后面的int size_t是一个一元表达式,size_t是一个为止的符号,当编译器遇到size_t length这样的语句时,将其代入之前的一元式,可以得到:int length,已没有未知符号,处理完毕。

下面是一个更复杂的例子:

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

typedef后面的void(*ptr_to_func) (int)是一个一元式,当处理到下面那句的时候,带入得到:void (*signal(int sig, ptr_to_func func)) (int)。该式中仍存在未知符号,在函数参数中的ptr_to_func func这个地方,将其带入一元式,结果为:void(*func) (int),最终的结果是void (*signal(int sig, void(*func)(int)))(int),处理完毕。这个式子看起来非常复杂,不过这的确就是ANSI C中signal的实际声明方式。

以上的分析可能没有太大的实际意义,具体在编译器中是怎样处理的可能会有所差别。不过至少让我破除了原来对typedef语法狭隘的理解,而且明晰了typedef与#define之间的区别。在实际使用中,我们应当意识到#define只是做文本替换,而typedef则是真正地声明了一种类型,在某些情况下,它们是不同的,比如以下的代码:

#define int_ptr int *
int_ptr a, b;    // 注意a和b的类型是不同的,展开后为int *a, b;
typdef char * char_ptr;
char_ptr c, d;   // c和d的类型相同,都是char *

转载于:https://my.oschina.net/jerryone/blog/88454

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值