声明的意义

当定义了一个变量时,它是什么意思呢,这里是一个简单的一次性解释声明的小程序,之后再改一下,可以一次运行,重复输入就OK了。

// 无法重复循环该程序
#include <stdio.h>
#include <ctype.h> // isalnum()
#include <string.h> // strcpy()
#include <stdlib.h> // atoi()
#define MAXTOKENS 100
#define MAXTOKENLEN 64

enum type_tag { // 0, 1, 2
    IDENTIFIER,
    QUALIFIER,
    TYPE
};

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

int top = -1;
struct token stack[MAXTOKENS]; // 保存第一个标识之前的所有标记
struct token this; // 保存刚读入的标记

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

enum type_tag classify_string();
void gettoken();
void read_to_first_identifier();

void deal_with_arrays();
void deal_with_function_args();
void deal_with_pointor();
void deal_with_declarator();

int main() {
//    while (1) {
        printf("> ");
        read_to_first_identifier();
        deal_with_declarator();
        printf("\n");
//    }

    return 0;
}

enum type_tag classify_string() {
    char *s = this.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() {
    char *p = this.string;

    while ((*p = getchar()) == ' '); // 跳过空格

    if (isalnum(*p)) { // 字母/数字
        while (isalnum(*++p = getchar()));
        ungetc(*p, stdin); // 吐回最后那个不是字母/数字
        *p = '\0'; // 字符串结束标识符
        this.type = classify_string(); // 取得字符串类型
        return;
    }

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

    this.string[1] = '\0'; // {或[类型
    this.type = *p;
    return;
}

void read_to_first_identifier() { // 读至第一个标识符
    gettoken();  // get a token
    while (this.type != IDENTIFIER) { // if not IDENTIFIER, continue
        push(this);
        gettoken();
    }
    printf("%s: ", this.string); // print the IDENTIFIER
    gettoken(); // the token after IDENTIFIER
}
// -----------------------------
void deal_with_arrays() {
    while (this.type == '[') {
        printf("array ");
        gettoken(); // 数字或']'
        if (isdigit(this.string[0])) {
            printf("%d ", atoi(this.string));
            gettoken(); // 读取']'
        }
        gettoken(); // 读取']'之后的一个;
        printf("of ");
    }
}

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

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

void deal_with_declarator() {
    // 处理标识符之后可能存在的数组/函数
    switch (this.type) {
        case '[':
            deal_with_arrays();
            break;

        case '(':
            deal_with_function_args();
    }

    deal_with_pointor();
    // 处理在读入到标识符之前压入到堆栈中的符号
    while (top >= 0) {
        if (stack[top].type == '(') {
            pop;
            gettoken(); // 读取’)‘之后的符号
            deal_with_declarator();
        }
        else {
            printf("%s ", pop.string);
        }
    }
}

比如:

> char *(* c[10])(int **p);
c: array 10 of pointer to function returning pointer to char
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值