C语言中复杂声明的解读和简化

  1. 使用声明的优先级规则解读声明
    • 解读一个C语言声明,首先要找到声明中的标识符,然后按照优先级次序依次读取
    • 优先级从高到低一次是:
      • 声明中被括号括起来的部分
      • 后缀操作符:()表示这是一个函数,[]表示这是一个数组
      • 前缀操作符:*表示这是一个指针
    • const关键字后紧跟着类型描述符则说明该const关键字作用于类型说明符,
      其它情况则作用于const左边紧邻着第一个*号

例1:下面使用上述规则解读这个声明

char* const *(*p[10])()

标识符为p,p被一对括号包住,所以把括号里面的东西当作一个整体来看,p的后缀是[],则p
是一个数组,p前面有一个星号,表示数组中的元素为指针,(*p[10])后面紧跟着(),则表示
这是一个指向函数的指针,且该函数没有参数,(*p[10])前面的紧挨着*,则表示该函数返 回一个指针,该指针指向一个类型为char的常量指针.

例2:下面使用上述规则解读这个声明

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无返回值的函数。

  1. 使用如下方式解读声明
    C语言复杂声明解读_解码环.png

使用该流程图解析上述例1:

剩余的声明所采取的步骤结果
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是一个数组,该数组元素为函数指针, 指向函数
没有参数,并返回一个指针,该指针指向只读的字符类型指针

上述的例2就不使用这种方法解读了,太繁琐了,建议使用优先级规则优先级规则解读复杂声明
3. 使用typedef简化复杂声明
使用typedef完全可以使上述声明简单易懂,对于char* const *(*p[10])()这个声明,
由上面分析可知数组p中的元素类型为函数指针,那么可以使用typedef为函数指针取别名

typedef char*const* (*PFN)();

然后在定义指针数组:

PFN fnAry[10];

那么fnAry和p是等价的。

对于

 void (*s(int sig,void(*func)(int)))(int);

这个声明,使用typedef简化如下:

typedef void(*PFN1)(int);
PFN1 s(int sig,PFN1 pfn);

可以看出使用typedef后,声明得到了极大的简化。

原文地址:https://www.cnblogs.com/UnknowCodeMaker/p/11040597.html