分析C语言的声明

原创 2007年09月14日 13:50:00

C语言的声明是让初学者最为头疼的地方之一,本文提供一种理解C语言声明的方法之一,仅供参考。

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

以下是一个例子:

char * const *(*next)();

按照规则,我们先看变量名"next",并注意到它直接被括号所括住,所以先把括号里的东西作为一个整体,得出"next是一个指向...的指针",然后考虑括号外面的东西,在星号前缀和括号后缀之间作出选择,B2规则告诉我们优先级较高的是右边的函数括号,所以得出"next是一个函数指针,指向一个返回...的函数",然后,处理前缀"*",得出指针所指的内容,最后,把"char * const"解释为指向字符的常量指针。

将以上分析结果加以概括,这个声明表示"next是一个指针,它指向一个函数,该函数返回另一个指针,该指针指向一个类型为char的常量指针",大功告成。

另外附一个将C语言声明翻译成通俗语言的程序,较为粗略,有兴趣的可以改进这个程序。

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define MAXTOKENS 100
#define MAXTOKENLEN 64

enum type_tag{IDENTIFIER,QUALIFIER,TYPE};

struct token{
 char type;
 char string[MAXTOKENLEN];
};

int top=-1;
struct token stack[MAXTOKENS];
struct token thistoken;

#define pop stack[top--]
#define push(s) stack[++top]=s

/*推断标识符类型*/
enum type_tag classify_string(void)
{
 char *s=thistoken.string;
 if(!strcmp(s,"const")){
  strcpy(s,"read-only");
  return QUALIFIER;
 }
 if(!strcmp(s,"volatile"))
  return QUALIFIER;
 if(!strcmp(s,"void"))
  return TYPE;
 if(!strcmp(s,"char"))
  return TYPE;
 if(!strcmp(s,"signed"))
  return TYPE;
 if(!strcmp(s,"unsigned"))
  return TYPE;
 if(!strcmp(s,"short"))
  return TYPE;
 if(!strcmp(s,"int"))
  return TYPE;
 if(!strcmp(s,"long"))
  return TYPE;
 if(!strcmp(s,"float"))
  return TYPE;
 if(!strcmp(s,"double"))
  return TYPE;
 if(!strcmp(s,"struct"))
  return TYPE;
 if(!strcmp(s,"enum"))
  return TYPE;
 if(!strcmp(s,"union"))
  return TYPE;
 return IDENTIFIER;
}

/*读取下一个标记到"thistoken"*/
void gettoken(void)
{
 char *p=thistoken.string;
 /*略过空白字符*/
 while((*p=getchar())==' ')
  ;
 if(isalnum(*p)){
  while(isalnum(*++p=getchar()))
   ;
  ungetc(*p,stdin);
  *p='/0';
  thistoken.type=classify_string();
  return;
 }

 if(*p=='*'){
  strcpy(thistoken.string,"pointer to");
  thistoken.type='*';
  return;
 }

 thistoken.string[1]='/0';
 thistoken.type=*p;
 return;
}

/*理解所有分析过程的代码段*/
void read_to_first_identifier(){
 gettoken();
 while(thistoken.type!=IDENTIFIER){
  push(thistoken);
  gettoken();
 }
 printf("%s is ",thistoken.string);
 gettoken();
}

void deal_with_arrays(){
 while(thistoken.type=='['){
  printf("array ");
  gettoken();
  /*数字或中括号*/
  if(isdigit(thistoken.string[0])){
   printf("0..%d ",atoi(thistoken.string)-1);
   gettoken(); /*读取']' */
  }
  gettoken();  /*读取']'之后的再一个标记*/
  printf("of ");
 }
}

void deal_with_function_args(){
 while(thistoken.type!=')'){
  gettoken();
 }
 gettoken();
 printf("function returning ");
}

void deal_with_pointers(){
 while(stack[top].type=='*'){
  printf("%s ",pop.string);
 }
}

void deal_with_declarator(){
 /*处理标识符之后可能存在的数组/函数*/
 switch(thistoken.type){
 case '[':
  deal_with_arrays();
  break;
 case '(':
  deal_with_function_args();
 }
 deal_with_pointers();
 /*处理在读入到标识符之前压入到堆栈中的符号*/
 while(top>=0){
  if(stack[top].type=='('){
   pop;
   gettoken(); /*读取')'之后的符号*/
   deal_with_declarator();
  }else{
   printf("%s ",pop.string);
  }
 }
}

int main()
{
 /*将标记压入堆栈,直到遇见标识符*/
 read_to_first_identifier();
 deal_with_declarator();
 printf("/n");
 return 0;
}

基于c语言的语句声明分析程序

  • 2009年01月19日 10:10
  • 3KB
  • 下载

C语言中声明和定义的区别——分析extern关键词。

一直很迷惑C语言中的声明和定义的有些实践中的用法,说迷惑实践是因为声明和定义的概念上的区别是很明确的。 定义和声明的区别(主要针对变量): 定义是要为变量分配存储空间,还可以在定义的时候为变量指定...

【C专家编程】第3章 分析C语言的声明

第3章 分析C语言的声明 声明 C语言中,对象的声明形式域它的使用形式尽可能相似 const int * ptr与int const * ptr相同 合法的声明存在限制条件 l  函数的返回值不能是一...

C专家编程:用python写cdecl程序,以分析C语言程序的声明语句

前两天阅读《C专家编程》第3章“分析C语言的声明”,书中提供了一个名叫 cdecl 的算法流程分析C语言声明。 输入C语言声明形式,用英语输出对应的描述。 我参照《C专家编程》“编程挑战”的设计,...

C专家编程——分析C语言的声明

C语言声明的语法有时会带来严重的问题——Dennis     声明的形式和使用的形式相似,这是C语言声明的一种缺陷。例如声明指针数组int *p[3];使用数组第四个元素*p[3]     在此,...

[C专家]分析C语言声明——只有编译器才会喜欢的语法

Kernighan和Ritchie成人,“C语言声明的语法有时会带来严重的问题。”(K&R,第二版,第122页)。C语言声明的语法对于编译器(或编译器设计者)的处理来说并不是什么大不了的事。但对于一般...

程序实现分析C语言的声明语句含义

本程序参考了《C专家编程》一书中第3章“分析C语言的声明”中图3-1(65页)以及71页、72页的伪代码实现。程序能完成基本分析功能。如有问题,欢迎给我留言讨论。 #include #incl...
  • lvsi12
  • lvsi12
  • 2012年11月30日 16:41
  • 516

《C专家编程》学习笔记(分析C语言的声明)

一、C语言声明的语法有时会带来严重的问题 1、

C编译器剖析_3.3 语法分析_C语言的外部声明(1)

3.3  C语言的外部声明_ExternalDeclaration     在分析完表达式和语句之后,《K&R》附录中关于标准C的6页文法,我们就已经差不多已经理解了一半,另外的3页文法基本上都是关...
  • SheIsC
  • SheIsC
  • 2015年02月05日 14:15
  • 1022

分析C语言的声明的优先级

C语言的声明是C语言区别于其他语言的一大亮点,本文主要讲解的是C声明的优先级规则。...
  • ladybai
  • ladybai
  • 2016年04月16日 16:16
  • 401
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:分析C语言的声明
举报原因:
原因补充:

(最多只允许输入30个字)