Typedef
typedef,也就是类型别名,可以定义某种类型的同义词,我感觉可以类比于引用,引用是作为某一个变量的别名,而类型别名,就像一个类型的引用一样。这个东西用的好,可以简化编码,使代码易于理解,不过这个东西就和宏一样,还是有一些“坑”的
别名声明
下面来看看怎么对一个类型声明一个别名
typedef 类型名 别名
如:
typedef double db
// db 是 double 的别名/同义词
typedef db* dbptr
// dbptr 是 double* 的别名/同义词
一些理解误区
但是,我们在一些使用了类型别名的语句中,可能会理所当然的将别名指向的本名带回语句当中理解,这本身是没问题的,但是我们的理解方式却要做一些变化。例如:
typedef char* newtype;
const newtype cptr = 0;
const newtype*ps;
如果我们将newtype
换回char*
,好像会有:
const char* cptr = 0; // cptr 看起来像是一个指向常量字符的指针(或者说是一个常量字符串)
const char* *ps; // ps 看上去像是一个指向常量字符的二级指针
但是,上面的理解是错误的!!!不信?试试去编译下面这段:
const newtype cptr = "123456";
原因是这样:当我们typedef
后,newtype
代表的是char*
这个整体,而我们之前替换回去的时候:
const char *cptr = 0;
这个整体被拆开了,本来const应当修饰的是char*
,但是到了这里变成了修饰char
而正确的理解方式应当是这样
// 这里为了方便理解加了括号,语法上是不允许的!
const (char*) cptr = 0; // 所以 cptr 应该是一个指向字符的指针常量
// 和下一句等价
char* const cptr = 0;
// 以下代码是合法的
char c = '0';
cptr = const (char*) cptr = &c;
char* const cptr = &c;
同理
const newtype *ps;
// 应该理解为
char* const *ps;
// 这应该是指向(指向字符的指针常量)的指针
// 以下代码是合法的
char* const cptr = 0;
const newtype *ps = &cptr;
char* const *ps = &cptr;
引用以下C++ Primer的说法,并作出了适当修改和说明
声明语句用到
newtype
时,其基本数据类型是指针(char*
),可是用char*
带回别名,重写声明语句之后,数据类型就变成了char
(char
和*
分开了),*
成为了声明的一部分。结果就是const char
成为了基本数据类型,前后两种声明含义截然不同,前者(未替换别名)声明了一个指向char
的常量指针,而后者声明了一个指向const char
的指针。