程序中经常会出现这样的情况:程序不能确定它已经读入的输入是否足够,除非超前多读入一些输入。读入一些字符以合成一个数组的情况便是一例:在看到第一个非数字字符之前,已读入的数的完整性是不能确定的。由于程序要超前读入一个字符,这样就导致最后有一个字符可能不属于当前所要读入的数的现象,此时要利用缓冲区对该字符存储,以便后续利用。
【例】逆波兰计算器中表示1.3475+1.2为1.3475 1.2 +
由于输入时要读取’.’ ’ ’ ‘+’ ‘-’ ‘*’ '/‘所以要对数字和小数点同其他运算符相区分,并将最后一个不属于1.2的’ ‘和’+'存入缓冲区加以保留,以便下次读取使用。
外部变量
因为外部变量可以在全局范围内访问,这就为函数之间的数据交换提供了一种可以替代函数参数与返回值的方式。缓存和栈都为外部变量提供了很好的寄存效果。
缓存
在逆波兰计算器应用中,缓存操作针对的是将字符串输入转化为double类型操作数的操作
getch
getch与getchar
缓冲区为空时,getch=getchar
缓冲区非空时,getch优先从缓冲区中读取字符
ungetch
填充缓冲区
存在当前字符不属于当前所要读入的数现象时,将当前字符压入缓冲区
#define BUFSIZE 1000
char buf[BUFSIZE];
//bufp指向最上层的空单元
int bufp=0;
// getch从缓冲区或外界取
int getch(void)
{
return(bufp>0)?buf[--bufp]:getchar();
}
// ungetch从外界压入缓存
void ungetch(int c)
{
if(bufp>=BUFSIZE)
printf("ungetch: too many characters\n");
else
buf[bufp++]
}
栈
在逆波兰计算器应用中,栈针对的是将字符串转化成double类型的数字的读取操作。
pop
弹出所需的操作数,指针减 return val[–sp];
push
压入结果或下次需要的操作数,指针增 val[sp++]=c;
// 定义栈
#define MAXVAL 100 /*栈val的最大深度*/
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;
}
getop()
- 跳过空白符 getch
- 非数字、小数点字符 s[0]=‘char’;s[1]=’\n’
- 数字字符s[0] 整数部分、小数点、小数部分
- 非数字字符,存入缓冲区 ungetch
#include<ctype.h>
int getch(s[]);
void ungetch(int);
int getop(char s[]){
while((s[0]=c=getch())==' '||c=='\t')/*存入最后一个空白符或空白符后的第一个非数字字符*/
;
s[1]='\0';
if(!isdigit(c)&& c!=='.')
return c; /*对于非数字字符直接输出字符串s[2]*/
i=0;
if(isdigit(c)) /*收集整数部分*/
while(isdigit(s[++i]=c=getch()))
;
if(c=='.')/*收集小数部分*/
while(isdigit(s[++i]=c=getch()))
;
s[i]='\0';/*输入非数字字符跳出while,字符串补'\0'*/
if(c!=EOF)
ungetch(c);
return NUMBER;
}
getop只会讲数字后面的一位非数字字符存入到缓冲区
test_getop
while((type=getop(s))!=EOF)
【例】输入123.456‘空格’’+’’-’ 回车方可运行getchar()
1.第一次:运行到空格处,type=NUMBER,‘空格’存入buf缓冲区
2.第二次:运行到+处,type=’+’
3.第三次:运行到-处,type=’-’
int main() {
char s[MAXCHAR];
int type;
type = getop(s);
if (type == NUMBER)
printf("%f\n", atof(s));
printf("buf[0]=%c\n", buf[0]);
type = getop(s);
if (type == '+')
printf("%c\n", '+');
type = getop(s);
if (type == '-')
printf("%c\n", '-');
}
运行结果