问题:c语言 #define NUMBER '0' 标识找到一个数 的含义是什么?
这是《THE C PROGRAMMING LANGUAGE》这本书里的逆波兰表达式的原题。
本文将给出 #define NUMBER '0' 标识找到一个数 的详细解释
这里我先贴出源代码
#include<stdio.h> #include<stdlib.h> #include<ctype.h> #define MAXOP 100 #define NUMBER '0' int getop(char []); void push(double); double pop(void); int getch(void); void ungetch(int); //atof函数:将字符串s转换成相应的双精度浮点数 int main(){ int type; double op2; char s[MAXOP]; while ((type = getop(s)) != EOF){ switch (type){ case NUMBER: push(atof(s)); break; case '+': push(pop()+pop()); break; case '*': push(pop()*pop()); break; case '-': op2 = pop(); push(pop()-op2); break; case '/': op2 = pop(); if(op2 != 0.0){ push(pop()/op2); } else printf("error:zero divisor\n"); break; case '\n': printf("\t%.8g\n",pop()); break; default: printf("error:unknown command %s\n",s); break; } } return 0; } #define MAXVAL 100 int sp =0; double val[MAXVAL]; void push(double f) { if(sp<MAXVAL) val[sp++] = f; else printf("error:stack full,can't push %g\n",f); } double pop(void) { if(sp>0) return val[--sp]; else{ printf("error:stack empty\n"); return 0.0; } } int getop(char s[]) { int i,c; while ((s[0] = c = getch()) == ' '|| c == '\t'); s[1] = '\0'; if(!isdigit(c) && c !='.') return c; i = 0; if(isdigit(c)) while (isdigit(s[++i] =c =getch())); if(c == '.') while (isdigit(s[++i] =c =getch())); s[i] = '\0'; if(c != EOF) ungetch(c); return NUMBER; } #define BUFSIZE 100 char buf[BUFSIZE]; int bufp = 0; int getch(void) { return (bufp>0) ? buf[--bufp] : getchar(); } void ungetch(int c) { if(bufp>=BUFSIZE) printf("ungetch:too many characters\n"); else buf[bufp++] = c; }
这个程序是描述逆波兰表达式的,这里我把全部代码贴出来了,其中包含NUMBER的地方有三处,第一个出现是在定义的地方,第二个出现是在switch case结构中,第三个出现是在getop函数的末尾,return一个NUMBER。
直接看默认注释“标识找到一个数”,难以理解,本人也是想了好久才有了一点心得。
1.首先我们阅读getop函数,这个函数的作用是获得操作数或者运算符的,遇到运算符,return c,即返回运算符。遇到数字或者带小数点的数字,它返回的是 NUMBER,但变量c里面的值是操作数。
2.然后看第二处代码
while ((type = getop(s)) != EOF){
switch (type){
case NUMBER:
push(atof(s));
break;
含义是:getop函数获得的值赋给type,然后根据获得的类型type用switch case结构进行识别进而有后面的进栈和出栈。
getop返回的运算符,case分支有运算符和它对应,getop返回NUMBER,刚好第一个分支NUMBER 和它对应,然后将输入的字符串用atof函数进栈,从而实现了整个输入的操作。
注1:由于switch case结构的要求,NUMBER必须是单字符的常量表达式,而且type必须是变量。
如果定义个char NUMBER=‘0’显然是变量,所以必须通过宏替换的形式,#define NUMBER '0',将常量变换成变量,且能满足case后面是常量表达式的要求。
注2:number这个必须是单字符,无论什么字符都不重要。
若是把#define NUMBER '0'换成#define NUMBER 'a',在代码中还是能正常运行,因为本来就没有影响。
书里写的'标识找到一个数'的真正含义我认为是'定义一个标记符'。