typedef 的那些事儿
目录
typedef 简述
typedef 是在计算机编程语言中用来为复杂的声明定义简单的别名,与宏定义有些差异。 它本身是一种存储类的关键字,与 auto、extern、mutable、static、register 等关键字不能出现在同一个表达式中。
关于这个问题,举个栗子:
typedef register int FAST_COUNTER; // 错误
编译通不过。问题出在你不能在声明中有多个存储类关键字。因为符号 typedef 已经占据了存储类关键字的位置,在 typedef 声明中不能用 register(或任何其它存储类关键字)。
typedef vs #define
#define 的优势
- #define 宏定义有一个特别的长处:可以使用 #ifdef, #ifndef 等来进行逻辑判断,还可以使用 #undef 来取消定义。
- #define 宏是预处理器处理的。
typedef 的优势
- typedef 也有一个特别的长处:它符合范围规则,使用 typedef 定义的变量类型其作用范围限制在所定义的函数或者文件内(取决于此变量定义的位置),而宏定义则没有这种特性。
- typedef 是编译器处理的。
typedef 实现复杂的变量声明
提问
在编程实践中,尤其是看别人代码的时候,常常会遇到比较复杂的变量声明,此时可以使用 typedef 做化简。下面是三个变量的声明,如果要使用 typdef 分别给它们定义一个别名,该如何实现?
/* 1. */ int *(*a[5])(int, char*); /* 2. */ void (*b[10]) (void (*)()); /* 3. */ double(*)() (*pa)[9];
答案与分析:
对复杂变量建立一个类型别名的方法很简单,你只要在传统的变量声明表达式里用类型名替代变量名,然后把关键字 typedef 加在该语句的开头就行了。
/* 1. */ int *(*a[5])(int, char*); //pFun 是我们建的一个类型别名 typedef int *(*pFun)(int, char*); //使用定义的新类型来声明对象,等价于 int* (*a[5])(int, char*); pFun a[5]; /* 2. */ void (*b[10]) (void (*)()); //首先为上面表达式蓝色部分声明一个新类型 typedef void (*pFunParam)(); //整体声明一个新类型 typedef void (*pFun)(pFunParam); //使用定义的新类型来声明对象,等价于 void (*b[10]) (void (*)()); pFun b[10]; /* 3. */ double(*)() (*pa)[9]; //首先为上面表达式蓝色部分声明一个新类型 typedef double(*pFun)(); //整体声明一个新类型 typedef pFun (*pFunParam)[9]; //使用定义的新类型来声明对象,等价于 double(*)()(*pa)[9]; pFunParam pa; //pa 是一个指针,指针指向一个数组,这个数组有 9 个元素,每一个元素都是“doube(*)()”--也即一个指针,指向一个函数,函数参数为空,返回值是“double”。
typedef 在跨平台时的优势
typedef 有另外一个重要的用途,那就是定义机器无关的类型,例如,你可以定义一个叫 REAL 的浮点类型,在目标机器上它可以获得最高的精度:
typedef long double REAL;
在不支持 long double 的机器上,该 typedef 看起来会是下面这样:
typedef double REAL;
并且,在连 double 都不支持的机器上,该 typedef 看起来会是这样:
typedef float REAL
你不用对源代码做任何修改,便可以在每一种平台上编译这个使用 REAL 类型的应用程序。唯一要改的是 typedef 本身。在大多数情况下,甚至这个微小的变动完全都可以通过奇妙的 条件编译1来自动实现。
typedef 的一些注意事项
注意事项一
typedef char* pstr; int mystrcmp(const pstr p1,const pstr p3);
用 GNU 的 gcc 和 g++ 编译器,是会出现警告的,按照顺序, const pstr
被解释为 char* const
(一个指向 char 的指针常量),而事实上, const char*
和 char* const
表达的并非同一意思(详见 C++ Primer 第四版 P112)。
char * const cp
: 定义一个指向字符的指针常数,即 const 指针,常指针。const char* p
: 定义一个指向字符常数的指针,即常量指针。char const* p
: 等同于 const char* p。
为了得到正确的类型,应当如下声明:
typedef const char* pstr;
注意事项二
typedef 遵循着和 #define 不一样的定义规则。规则比较奇怪,这里也是举个栗子说明:
定义有 81 个字符元素的数组,无 typedef 版本:
char line[81]; char text[81];
定义有 81 个字符元素的数组,有 typedef 版本:
typedef char Line[81]; Line text,line;
脚注:
#if、#else、#elif、#endif 等等,#define 的情况会使用 #ifdef 和 #ifndef(也是用 #endif 结尾)。
Generated by Emacs 26.x(Org mode 9.x)
Copyright © 2014 - 皐月中二 - Powered by EGO
- Analysized by