首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

小型计算器程序解决办法

2012-05-04 
小型计算器程序这是一段出现在课本《c程序设计语言》中的程序,请高手解释一下具体的实现原理:#includestdio

小型计算器程序
这是一段出现在课本《c程序设计语言》中的程序,请高手解释一下具体的实现原理:

#include<stdio.h>
#include<stdlib.h>

#define MAXOP 100
#define NUMBER '\0'

int getop(char []);
void push(double);
double pop(void);

/* 逆波兰计算器程序 比如: 当输入: 4 5 - 6 8 * + 时, 则输出: 47 */
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;
  }
  }
  getch();
  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()
{
  if(sp > 0)
  return val[--sp];
  else{
  printf("error: stack empty\n");
  return 0.0;
  }
}


#include<ctype.h>

int getch(void); 
void ungetch(int);


/* 请解释此段代码的工作原理 */
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) /* getch()函数在标准库里已定义, 这里再定义一次不会和标准库冲突吗?*/
{
  return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c)
{
  if(bufp >= BUFSIZE)
  printf("ungetch: too many characters\n");
  else
  buf[bufp++] = c;
}

不好意思代码有点长,但觉得此程序很经典,想彻底了解一下,请高手指教。先谢谢啦

[解决办法]
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'; 
/******************************************
*下面把最后一个字符放到缓冲区,
*下一个循环要从buf中读最后一个字符,
*如果buf为空则从stdin中读一个字符。
*其实BUFSIZE为1就够了。
******************************************/
if (c != EOF) 
ungetch(c); 
return NUMBER; 



getch()不是标准函数,它是微软发明的函数。
你可以查一下《C参考大全》,或者直接看C99文档。

我这里没有微软的编译器,所以无法测试会不会冲突,
GCC上编译是没有问题的。
在微软编译器上是否会冲突就要看编译器是怎么做的了,
反正是微软自己发明的,微软想让它冲突就冲突,想不冲突也有办法。
[解决办法]

C/C++ code
/* * 如果输入的第一个字符不是数字也不是小数点,那么把它写进s并返回此字符 * 否则读取完整的数字写入s,并返回一个标志NUMBER */int getop(char s[]) {     int i, c;     while ((s[0] = c = getch()) == ' ' || c == '\t')         ;  // 忽略空格和TAB    s[1] = '\0';  // 使s成为一个有结束符的完整字符串    if (!isdigit(c) && c != '.')         return c;  // 如果第一个子符不是数字也不是小数点,那么就返回这个字符。这时候上面的s[1]=0就有用了,因为main里要把s当作字符串处理    i = 0;     if (isdigit(c))         while (isdigit(s[++i] = c = getch())) /* 收集整数部分 */             ; // 把输入的数字保存到s,直到输入一个非数字    if (c == '.')         while (isdigit(s[++i] = c = getch())) /* 收集小数部分 */             ; // 把输入的数字保存到s,直到输入一个非数字     s[i] = '\0';  //字符串结束符    if (c != EOF)         ungetch(c);  // 把一串数字后面紧跟着的第一个字符(很可能是运算符)保存到缓冲区,下次再读取    return NUMBER; }
[解决办法]
C/C++ code
//其实是把整个输入的表达式当成一个字符串来看待int getop(char s[]) {     int i, c;     while ((s[0] = c = getch()) == ' ' || c == '\t')         ;     s[1] = '\0';      //'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; } 

热点排行
Bad Request.