对于声明,应该按下面的步骤来进行解释:
1) 声明从它的名字开始读取,然后按照优先级顺序依次读取
2) 优先级顺序
a) 括号括起来的部分
b) 后缀操作符,()表示函数,[]表示数组
c) 前缀操作符,*表示指针
3) 如果const或volatile关键字后面紧跟类型说明符,那么他作用于类型说明符,其他情况下,作用于其左边紧邻的指针星号。
根据这个原则,我们可以得到下面的代码
#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 that; #define pop stack[top--] #define push(s) stack[++top] = s enum type_tag classify_string(void) { char *s = that.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, "union")) return TYPE; if (!strcmp(s, "enum")) return TYPE; return IDENTIFIER; } void gettoken (void) { char *p = that.string; while ((*p = getchar()) == ' '); if (isalnum(*p)){ while (isalnum(*++p = getchar())); ungetc(*p, stdin); *p = '\0'; that.type = classify_string(); return; } if (*p == '*') { strcpy(that.string, "pointer to"); that.type = *p; return; } that.string[1] = '\0'; that.type = *p; return; } void read_to_first_identifier (){ gettoken(); while (that.type != IDENTIFIER) { push(that); gettoken(); } printf("%s is ", that.string); gettoken(); } void deal_with_arrays() { while (that.type == '[') { printf("array "); gettoken(); if (isdigit(that.string[0])) { printf("0..%d ", atoi(that.string)-1); gettoken(); } gettoken(); printf("of "); } } void deal_with_function_args() { while (that.type != ')') { gettoken(); } gettoken(); printf("function returning "); } void deal_with_pointers () { while (stack[top].type == '*') { printf("%s ", pop.string); } } void deal_with_declarator() { switch(that.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 (*a)()
结果:
a is pointer to function returning int
过程:
读入int
读入(
读入*
读入a
a是标识符,退出开始的循环
输出a is
读入),由于有)暂不读入后面字符,弹出*,输出pointer to,
一直弹出,直到(则继续读取后面的字符(,
因为读到(,输出function returning.
int *a()
结果:
a is function returning pointer to int
过程:
读入int
读入*
读入a
a是标识符,退出开始的循环
输出a is
读入(判断出a是个函数输出function returning
读取*,输出pointer to
读取int,输出int