淹死的鱼
wangquzhi@gmail.com1
April10,2011
1
如果您发现有文中所述有任何不妥或者错误之处,还请不吝赐教。
看一下下面的代码。
#definePOINT_Dint*typedefint*POINT_T;
两行代码在功能上可以说是一模一样的,只是在实现方式上小小不同罢了。可就是这点小小的不同,有可能让你和你的编译器闹翻了脸。编译器就像女朋友,像老婆,吵起来的时候,错的只能是你。让我们看看我们错在哪里了。
#definePOINT_Dchar*typedefchar*POINT_T;voidmain(void){
POINT_Dme1,me2;POINT_Tta1,ta2;
char*i=\"Itismyfault!\";ta1=i;ta2=i;me1=i;me2=i;}
在上面的代码中,我们是想定义4个指向char的指针,然后将一个字符串的首地址分别赋给它们。编译上面的代码。咦!怎么有个Warning?我的gcc给出了这样的警告提示:
14:
warning:
assignmentmakesintegerfrompointer
withoutacast
1
女朋友的话千万不要不当回事,虽然有时候却实很莫名其妙。这个警告说程序中存在赋值时的类型不一致。可是哪里不一致呢?没错,就是最后一个语句。程序在预编译后,第六行多成了:
char*me1,me2;
也就是说,实际上me2的类型并不是我们之前认为的char*。于是,蓦然回首,发现悲剧的依然是me,Ta依旧是那么正确。到此,typedef的优点便被小小地展示出来了,也就是说,typedef与#define相比,typedef能够正确的处理指针,而#define却会产生“歧义”的错误。但是除此之外,typedef其实还有一个优点,就是typedef是遵守C语言作用域规则的。它可以在函数里面声明,这时typedef所声明的类型的生存周期就仅限于这个函数(当然你也可以说可以用#define和#undef达到相同的效果,但是,这个起码要简单点吧?)。
到这里,你是不是要说,那以后只要记得全部都用typedef就可以高枕无忧了。本人水平有限,真的不敢给你作这样的保证,因为起码下面的例子,如果你对typedef没有真正理解,那么它也有些“迷人”。但是在看下面例子之前首先声明,如果你真的在这里弄错了,我认为这个并不能算是typedef的缺点,而应该怪你没有真正理解typedef。尽管如此,我认为有必要提一下这个例子。
typedefchar*POINT_T;voidmain(void){
char*i=\"Itismyfault!\";constchar*ta
=i;
constPOINT_Tme=i;ta++;me++;}
2
代码中定义了两个指向char的指针,然后试图将这指针自加。编译,我得到了这样的错误提示:
11:error:incrementofread-onlyvariable‘me’由于POINTT在这里已经是一个新的数据类型,所以const所限定的就是整个“char*”,而不是char。
其实#define并没有那么坏。#ifdef就是它很好的一个优点。
3
因篇幅问题不能全部显示,请点此查看更多更全内容