“typedef”,大家都很熟悉,它是用来为内建类型或用户自定义类型引入助记符号的。但是有很多人(甚至是有经验的程序员)仍然将typedef理解为“宏”,或者至少按照“宏”的语法和语义去推断typedef的相关规则。
下面就是这个例子可以给这些人敲一个警钟(还是“悬崖勒马”吧):
typedef int *pitype;
extern const pitype pi;//****
此处,pi是什么类型的?是“const int *”么?
非也,pi的类型是“int *const”!
也就是说,const和pitype都直接作用到变量pi上!(如果按照“宏”的方式去理解,则const作用在pitype上,而非直接作用于pi上面)
此例虽然简单,但是如果不小心,也可能让大侠们跌份,所以还是注意一点儿的好:)
我们知道,如果有int *p, a; 那么p是int*类型的,而a是int类型的。原因是*似乎与标识符结合得更紧密。但是,如果有typedef int* PINT;那么PINT p, a;中的p,a就都是int*类型的了。
所以,对于int const *p;我同意楼主“const修饰词和其他类型修饰是并列的”的说法,但不认同“p的种属有两个,int 和 const*”。我认为,首先*是与p结合的,所以它是一个指针,然后从右往左,它指向的内容是const的,它指向的内容是int的。对于const int *p也是一样,指向是int的,指向是const的。所以这两种定义产生的效果是一样的。至于int *const p;同样以*为右结合来看,p是一个指针,它的属性是const的,再看*的左边,p这个指针是指向int的。
但是,对于typedef,却把*的结合型置左了,产生了一种新的“合一的”类型int*。所以对于const PINT p; 现在PINT中包含的*已经不再与p结合了,而是一种新的类型,这种类型就可以想象为int。那么const int p;中的const修饰的是p的内容为const,那么当然const PINT p中的const就是修饰int*类型的p的值为const。
所以,我认为关键在于一般的指针写法中的*是右结合,要以*分割为左右两部分来看,右边的是这个指针的属性,左边的是指向内容的属性。
但是,对于typedef,却把*的结合型置左了,产生了一种新的“合一的”类型int*。所以对于const PINT p; 现在PINT中包含的*已经不再与p结合了,而是一种新的类型,这种类型就可以想象为int。那么const int p;中的const修饰的是p的内容为const,那么当然const PINT p中的const就是修饰int*类型的p的值为const。