指针声明示例:
0.const char * char_p; <==> char const * char_p;
解析: 指针所指的对象是只读的,但是指针是可以修改的。
1.char * const char_p;
解析:指针所指的对象是可以修改的。但是指针是只读的。
2.const char * const char_p;
解析:指针与指针所指的对象都是只读的
3. char * char_p;
解析:指针与指针所指的对象都是可以修改的的
4.char * char_p[20]
解析: char_p是一个数组,每一个元素为char *
5. char (*char_p)[20];
解析: char_p是一个指针,指向一个含有20个char的数组;
6. int(*fun())();
解析:fun为一个函数,返回一个函数指针。
7.int(*fun())[];
解析:fun为一个函数,返回一个int类型的数组
8.int(*fun[])();
解析:fun为一个数组,每一个元素为一个函数指针。
9.char * const * (*next)()
解析:fun是一个函数指针,返回一个指向(指向char类型的常量指针)的指针。
10. char* (*cc[10] )(int **p);
解析:cc是一个数组,每一个元素为接受一个int**的参数,返回char* 的函数
11. void ( * signal(int, void(*func)(int)) )(int)
解析:signal是一个函数。
signal 的参数为:int和一个函数指针。 该函数指针指向一个接受int类型参数返回void类型的函数
signal的返回值为一个函数指针,该函数指针为:一个接受int类型参数返回void类型的函数
c语言声明的优先级规则:
0.声明从它的名字开始分析,然后按照优先级顺序依次读取。
1.优先级高迪依次是:
00 声明中被括号括起来的部分
01 后缀操作符:括号()表示一个函数,方括号[]表示一个数组
02 前缀操作符:星号*表示“指向...的指针”
2. 如果const和volatile关键字后面紧跟类型说明符(如long,int等),那么它作用于类型说明符。在其他情况下,const和volatile关键字作用于它左边紧邻的指针星号(*)。
typedef关键字
typedef类似于宏文本替换-它并没有引入新类型,而是为现有类型取一个新名字。
tpedef的格式与变量声明完全一样,只是多了typedef关键字,向你提醒它的实质。
示例:
typedef void(*ptr_to_func)(int);
void ( * signal(int, void(*func)(int)) )(int) --> ptr_to_func signal(int,ptr_to_func);
建议:
0.不要在一个typedef中放入多个声明,如下所示:
typedef int * ptr,(fun)(),array[5];
ptr 是“指向int的指针”类型
fun是“指向返回值为int的函数的指针”类型
array是“长度为5的int类型数组”类型
1.不要将typedef嵌入到声明中间部分。
typedef与宏文本替换的区别:
0.可以使用其他类型说明符对宏类型名进行扩展,但对typedef所定义的类型名却不能这样做。
#define peach int
unsigned peach i ; //没问题
typedef int banana;
unsigned banana i;// 错误!非法
1.在连续几个变量的声明中,用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的指针。
typedef使用情况:
0.数组,指针及函数的组合。
1.可移植类型。typedef unsigned int size_t;
2.为强制类型转换提供一个简单的名字。
3.避免在用在struct结构定义中。struct定义中,始终使用结构标签,即使它并非必须。这种做法可以使代码更清晰。