分析C语言的声明---《C专家编程》

本文详细解析了C语言中的声明器概念和声明的形成,强调了声明的优先级规则,提供了理解声明的步骤和方法。通过实例演示如何将复杂的声明分解并转化为通俗语言,介绍了使用堆栈处理声明的思路,并给出了相关函数的实现和编译执行结果。
摘要由CSDN通过智能技术生成

1. 声明是如何形成的

声明器(declarator) 是C语言中所有声明的核心,简单的说:声明器就是标识符以及与它组合在一起的任何指针、函数括号、数组下表等,如下表所示:

C语言中的声明器

上表可以简化为一个公式:声明器 = 直接声明器( 标识符 or 标识符[下标] or 标识符(参数) or (声明器) ) + (零个或多个指针)

声明器只是C语言声明的一个部分,C语言中的声明 = 至少一个类型说明符 + 一个声明器 + 零个或多个其他声明器 + 一个分号,如下表所示:

C语言中的声明

2.优先级规则

要理解一个声明,必须要懂得其中的优先级规则,它高度简洁,可惜极不直观。下面给出一种方法,用通俗的语言把声明分解开来,分别解释各个组成部分。

理解C语言声明的优先级规则:

  • A 声明从它的名字开始读取,然后按照优先级顺序依次读取
  • B 优先级从高到低依次是:
  1. 声明中被括号括起来的部分
  2. 后缀操作符:括号()表示这是一个函数,[]则表示这是一个数组。
  3. 前缀操作符:星号* 表示"指向…的指针“
  • C 如果const或volatile关键字后面紧跟类型说明符(如int,
    long等),那么它作用于类型说明符,在其他情况下,const或volatile关键字作用于它左边紧邻的指针星号。

按照上面的优先级规则,可以用下图直观的解析。C语言中的声明读起来并没有固定的方向,一开始,我们从左边开始向右找寻,直到找到第一个标识符,当声明中的某个符号与图中所示匹配时,便把它从声明中处理掉,以后不再考虑。在具体的每一步骤上,我们先查看右边的符号,然后再看左边,直到所有的符号都处理完毕。

如何解析C语言的声明

下面给出一个例子,用上图所示的方法分析这个声明:

char * const *(*next)();

分析一个C语言声明的步骤

##3.把C语言声明翻译成通俗语言的程序

由于声明解析并非顺序进行,使用堆栈存储各个标记更方便处理。我们从左向右读取,把各个标记依次压入堆栈,直到读到标识符为止,然后继续向右读取一个标记,判断是否为数组或函数。接着观察标识符左边的标记(需要从堆栈中弹出)。一个标记需要存储本身字符及其类型,故使用一个结构体存储一个标记,数据结构大致如下:

#define MAXTOKENLEN	64		//每个标记的最长长度
#define MAXTOKENS	100		//一条声明中的最大标记数量

/*定义类型标签	标识符		限定符	   类型*/
enum type_tag{
   IDENTIFIER, QUALIFIER, TYPE};

/*声明一个标记结构*/
struct token{
   
	char type;
	char string[MAXTOKENLEN];
};

struct token stack[MAXTOKENS];		/*保存第一个标识符之前的所有标记*/
struct token this;					/*保存刚读入的那个标记*/

int top = -1;		/*栈顶索引*/

#define pop 	stack[top--]		/*出栈*/
#define push(s) stack[++top] = s	/*入栈*/

定义好数据结构后,main函数主程序要做的第一步是找出标识符,然后按上面的解析流程图处理标识:

int main(void)
{
   
	read_to_first_identifer();  //将标记压入堆栈中,直到遇到第一个标识符
	deal_with_declarator();    //处理标识
	printf(".\n");
	return 0;
}

找出第一个标识符的函数read_to_first_identifer()可以由更通用的获取下一个标记到this的函数void gettoken(void)实现,且需要判断标记为类型描述符、限定符还是标识符,判断标记类型可以由enum type_tag classify_string(void)函数实现,代码如下:

/*宏声明一种更直观的字符串表示格式*/
#define STRCMP(a,R,b) (strcmp(a,b) R 0)

/*推断标记的类型*/
enum type_tag classify_string(<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流云IoT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值