巩固一下typedef关键字的用法...
用法
typedef是 C 语言的关键字之一,人尽皆知的用法就是“为一个类型取别名”,比如:
1 | typedef unsigned int size_t; |
或者:
1 | typedef struct Student student; |
还有:
1 | typedef struct Node* PtrtoNode; |
类似的例子有很多,但实际上“为一个类型取别名”这种说法是不严谨的。私认为typedef关键字不仅仅是“取别名”,还要从语义的角度上去理解typedef的行为。
比如:
1 | typedef int Arr[5]; |
从语义的角度而言,在上述代码中,Arr是一种“新类型”(这里的新类型其实并不是真正意义上新类型),表示元素个数为 5 的int数组,对应的a是一个指向元素个数为 5 的int数组的数组指针。对比类型一样、用基本类型声明的数组指针parr,也可以看出使用typedef带来的便利性。
实际上,熟悉 C++ 的同学,可能会发现typedef和using的功能有点类似。
类似的用法,还有声明函数指针的用法,如下:
1 | typedef void (*pfun)(int); |
上述代码中,声明了一个返回值为void,参数为一个int的函数指针类型pfun。
陷阱
这里,还需要提一下typedef和const关键字一起使用时的陷阱——千万不要把typedef和#define的文本替换混为一谈。
比如:
1 |
|
在阅读下面的讨论之前,需要理解const typename *和typename * const的区别。
如果认为typedef是文本替换,那么const pchar str与const char *str一致,对应语句*str = 'g';就会出错,而str = s2;就会正常执行(可以对比下面const char *和const int相关的代码)。但事实上,结果正好相反,编译器认为*str = 'g';正确、str = s2;错误,这说明,编译器并不认为str是一个const char *。
从语义的角度来理解,pchar的类型是char型的指针,在其前面加上一个const,表示这个指针是一个常量,所以const pchar的实际类型是char * const,而不是const char *,这点从后面的代码也可以对比出来。
最后需要说明的是,typedef的用法是 C 的标准规定的,本文只是验证如何使用,而不是证明这是编译器的黑魔法😂。