int *p[3]; 一个int类型的指针数组
char (*j) [20]; 一个指向数组的指针
const int * grape;
int const * grape;
int * const grape_jelly;
在最后一种情况下,指针是只读的,而另外两种情况下,指针所指向的对象是只读的。
函数的返回值不能是一个函数,所以像foo()()是非法的。
函数的返回值不能是一个数组,所以像foo()[]是非法的。
数组里面不能有函数,所以像foo[]()是非法的。
但是像下面这样则是合法的:
函数的返回值允许是一个函数指针,如:int( *fun())();
函数的返回值允许是一个指向数组的指针,如:int(* foo())[];
数组里面允许有函数指针,如:int (* foo[])();
在结构中,每个成员依次存储,而在联合中,所有的成员都从偏移地址零开始存储。这样,每个成员的位置都重叠在一起,在某一时刻,只有一个成员真正存储于该地址。
联合一般用于节约空间,因为有些数据项是不可能同时出现的,如果同时存储它们显然颇为浪费。
关于枚举
枚举(enum)通过一种简单的途径,把一串名字与一串整型值联系在一起。
enum size {small = 7, medium , large = 10, humugous };
缺省情况下,整型值从零开始,如果对列表中的某个标识符进行了赋值,那么紧接其后的那个标识符的值就比所附的值大1,然后类推。枚举有一个优点:#define定义的名字一般在编译时被丢弃,而枚举名字则通常一直在调试器中可见,可以在调试代码时使用它们。
在typedef和宏文本替换之间存在一个关键性的区别。
首先,可以用其他类型说明符对宏类型名进行扩展,但对typedef所定义的类型名却不能这样做,如下:
#define peach int
unsigned peach i;/* 没问题*/
typedef int banana;
unsigned banana i;/* 错误,非法*/
其次,在连续几个变量的声明中,用typedef定义的类型能够保证声明中所有的变量均为同一种类型,而用#define定义的类型则无法保证,如下:
#define int_ptr int *
int_ptr chalk, cheese;
经过宏扩展,第二行变为:
int * chalk, cheese;
这使得chalk和cheese成为不同的类型,就好像是辣椒酱与细香舂的区别:chalk是一个指向int的指针,而cheese则是一个int。相反,下面的代码:
typedef char * char_ptr;
char_ptr Bently, Rolls_Royce;
Bently 和Rolls_Royce的类型依然相同。虽然前面的类型名变了,但它们的类型相同,都是指向char的指针。