把c语言中的声明用程序翻译成通俗的语言

来源:互联网 发布:淘宝怎么设置id限购 编辑:程序博客网 时间:2024/04/29 20:41

理解c语言的优先级规则:

A

 声明从它的名字开始读取,然后按照优先级次序一次读取

B

优先级从高到底依次是:

b1  声明中被括号括起来的那部分

b2 后缀操作符

      括号()表示这是一个函数,而方括号【】表示这是一个数组

b3 前缀操作符,星号*表示“指向。。。的指针”

C

如果const(或volatile)关键字的后面紧跟类型说明符(如int,long等),那么它作用于类型说明符,在其他情况下作用于它左边

紧邻的指针*号。

如  char * const*(*next)();

     上式表示“next是一个指针,它指向一个函数,这个函数返回另外一个指针,该指针指向一个类型为char的常量指针”

这里有一个设计方案,主要的数据结构是一个堆栈,我们从左向右读取,把各个标记依次压入堆栈,知道读到标识符为止,然后我们继续向右读入一个标记,也就是标识符右边的那一个标记,接着观察标识符左边的那个标记(需要从堆栈中弹出)

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#define MAX_LEN 100enum type_token {IDENTIFIER,QUALIFIER,TYPE};typedef struct token{char string[100];char type;}token;token tmp_token;typedef struct stack{token array[MAX_LEN];int top;}stack;struct stack token_stack;void init(stack *sta){sta->top=-1;}int push(stack *sta,token s){if(sta->top>=254){printf("the stack is full.\n");return 1;}else{sta->array[++(sta->top)]=s;}return 0;}token pop(stack *sta){if(sta->top==-1){printf("ERROR,the stack is empty!\n");}else{return sta->array[(sta->top)--];}}int stack_empty(const stack s){if(s.top==-1)return 0;elsereturn 1;}token top_stack(const stack s){if(stack_empty(s)==0){printf("ERROR the stack is empty!\n");}elsereturn s.array[s.top];}enum type_token classify_string();void gettoken(){//读取token函数,如果是字母,数字,下划线就一直读取,否则就停止存入tmp_token中处理memset(tmp_token.string,'\0',sizeof(tmp_token.string));//先把tmp_token清空char *p=tmp_token.string;while((*p=getchar())==' ');//略过空白字符if(isalnum(*p) || *p=='_'){//读入的标志符要是字母,数字或者下划线,表示是标志符while(1){*(++p)=getchar();if(isalnum(*p) || *p=='_')continue;elsebreak;}ungetc(*p,stdin);//把非满足的字符放回缓冲区,下次再用*p='\0';tmp_token.type=classify_string();return;}if(*p=='*'){strcpy(tmp_token.string,"pointer to ");tmp_token.type='*';return;}tmp_token.string[1]='\0';tmp_token.type=*p;return;}enum type_token classify_string(){//推断标志符的类型char *s=tmp_token.string;if(!strcmp(s,"const")){strcpy(s,"read-only ");return QUALIFIER;}if(!strcmp(s,"volatile")) return QUALIFIER;if(!strcmp(s,"extern")) 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,"union")) return TYPE;if(!strcmp(s,"enum")) return TYPE;return IDENTIFIER;}void read_first_identifier(){gettoken();while(tmp_token.type!=IDENTIFIER){push(&token_stack,tmp_token);gettoken();}printf("%s is ",tmp_token.string);gettoken();}void deal_with_array(){while(tmp_token.type=='['){printf("array");gettoken();if(isdigit(tmp_token.string[0])){printf(" 0..%d ",atoi(tmp_token.string)-1);gettoken();}gettoken();//读取‘】’之后的tokenprintf("of ");}}void deal_with_function(){while(tmp_token.type != ')')gettoken();gettoken();printf(" function returning ");}void deal_with_pointer(){token t;t=top_stack(token_stack);while(t.type=='*'){printf("%s",t.string);pop(&token_stack);t=top_stack(token_stack);}}void deal_with_declarator(){//递归处理的过程switch(tmp_token.type){case '[': deal_with_array();break;case '(': deal_with_function();}deal_with_pointer();while(stack_empty(token_stack)==1){token t=top_stack(token_stack);if(t.type=='('){pop(&token_stack);gettoken();//读取‘)’之后的符号deal_with_declarator();}else{printf("%s",pop(&token_stack).string);}}}int main(){init(&token_stack);    read_first_identifier();deal_with_declarator();printf("\n");return 0;}

原创粉丝点击