例1:下面使用上述规则解读这个声明css
char* const *(*p[10])()
标识符为p,p被一对括号包住,因此把括号里面的东西看成一个总体来看,p的后缀是[],则p
是一个数组,p前面有一个星号,表示数组中的元素为指针,(*p[10])后面紧跟着(),则表示
这是一个指向函数的指针,且该函数没有参数,(*p[10])前面的紧挨着*,则表示该函数返 回一个指针,该指针指向一个类型为char的常量指针.html
例2:下面使用上述规则解读这个声明git
void (*s(int sig,void(*func)(int)))(int);
标识符为s,s被一对括号包住,因此将(*s(int sig,void(*func)(int)))做为一个总体
分析,s后面紧跟着一对括号,则表示s是一个函数,s的第一个参数为int,第二个参数是一个
函数指针,该函数指针指向一个参数为int无返回值的函数;此时函数s的参数解读完毕,那么
剩下未解读的部分都是s的返回值,s的左边紧挨着*号,则表示s的返回值是一个指针,又由于
(*s(int sig,void(*func)(int)))后面紧跟着一对()则表示该指针为函数指针,指向一个参数为int无返回值的函数。github
使用该流程图解析上述例1:web
剩余的声明 | 所采起的步骤 | 结果 |
---|---|---|
char* const *(*p[10])() | 第1步 | 表示"p是....",这里先找出声明中的表示符为p |
char* const *(* [10])() | 第2步 | 表示"p是....的数组",这里肯定p为数组,接下来 要肯定数组p中的元素类型 |
char* const *(* )() | 第5步 | 表示数组元素类型为"指向....的指针",接下来 要肯定指针的类型 |
char* const *( )() | 第4步 | *p[10]已经处理完成,去掉用来包裹他们的一对 括号 |
char* const * () | 第2步 | 不符合,转到第3步 |
char* const * () | 第3步 | 表示"无参,返回....的函数",接下来肯定函数的 返回值类型 |
char* const * | 第5步 | 表示"指向....的指针" |
char* const | 第5步 | 表示"只读" |
char* | 第5步 | 表示"....的指针" |
char | 第6步 | char |
把上面的解析串起来可推导出:p是一个数组,该数组元素为指向无参并返回指向只读字符类型的指针的函数。
其实上面描述并不容易理解,能够这样描述:p是一个数组,该数组元素为函数指针, 指向函数
没有参数,并返回一个指针,该指针指向只读的字符类型指针json
上述的例2就不使用这种方法解读了,太繁琐了,建议使用优先级规则优先级规则解读复杂声明
3. 使用typedef简化复杂声明
使用typedef彻底能够使上述声明简单易懂,对于char* const *(*p[10])()这个声明,
由上面分析可知数组p中的元素类型为函数指针,那么能够使用typedef为函数指针取别名数组
typedef char*const* (*PFN)();
而后在定义指针数组:ruby
PFN fnAry[10];
那么fnAry和p是等价的。bash
对于markdown
void (*s(int sig,void(*func)(int)))(int);
这个声明,使用typedef简化以下:
typedef void(*PFN1)(int); PFN1 s(int sig,PFN1 pfn);
能够看出使用typedef后,声明获得了极大的简化。