⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 visualc++calulator.cpp

📁 这个是用Visual C++实现的计算器源代码
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define MAXOP    100
#define NUMBER    '0'    // signal that a number was found
#define EMPTY    0
enum Optype { ND, TOR };    // ND for operand, TOR for operator

union Era
{
  double nd;    // op.era.nd
  char tor;    // op.era.tor
};

struct Op
{
  int max;
  int top;
  enum Optype type;
  union Era *era;
};

struct Op *create_stack(int max, enum Optype);
void push(union Era, struct Op *);
union Era pop(struct Op *);
void nullerr(void);
int getop(char []);
double operate(struct Op *opnd, struct Op *optor);
void print_stack(struct Op *op);
char top_tor(struct Op *);

int
main()
{
  int c;
  char s[MAXOP];
  union Era era;
  struct Op *opnd;
  struct Op *optor;

  opnd = create_stack(MAXOP, ND);
  optor = create_stack(MAXOP, TOR);

  printf(" 本程序可进行“加减乘除(+ - * /)”四则混合运算。\n");
  printf(" 输入 q 或按 Ctrl+C 退出程序。\n");
  printf(" 输入算式后按回车即可算出答案:\n\n");

  while ((c = getop(s)) != EOF) {
    switch (c) {
    case NUMBER:
      if (opnd->top > optor->top + 1) {    // 如果是逆波兰算式
    printf("\tparse error\n");
    while (getchar() != '\n')
      /*void*/;
    opnd->top = EMPTY;
    era.nd = 0.0;
      }
      else
    era.nd = atof(s);
      push(era, opnd);
      break;
    case '+':        // + 和 - 优先级最低,把除了 '(' 以外的全部操作符弹出后入栈
    case '-':
      if (optor->top == EMPTY) {
    era.tor = c;
    push(era, optor);
      }
      else {
    while (optor->top > EMPTY)
      if (top_tor(optor) == '(')
        break;
      else {
        era.nd = operate(opnd, optor);
        push(era, opnd);
      }
    era.tor = c;
    push(era, optor);
      }
      break;
    case '*':              // 乘除优先级最高,把相同优先级的乘和除弹出后入栈
    case '/':
      if (optor->top == EMPTY) {
    era.tor = c;
    push(era, optor);
      }
      else {
    while (optor->top > EMPTY)
      if (((era.tor = top_tor(optor)) == '+')
          || (era.tor == '-')
          || (era.tor == '('))
        break;
      else {
        era.nd = operate(opnd, optor);
        push(era, opnd);
      }
    era.tor = c;
    push(era, optor);
      }
      break;
    case '(':        // '(' 不作运算,直接放入optor栈。
      era.tor = c;
      push(era, optor);
      break;
    case ')':        // 把 '(' 之前的全部操作符弹出,计算后把 '(' 也弹出
    while (optor->top > EMPTY)
      if (top_tor(optor) == '(')
        break;
      else {
        era.nd = operate(opnd, optor);
        push(era, opnd);
      }
    pop(optor);
      break;
    case '\n':        // 把余下的操作符全部弹出,计算后输出结果
      if (opnd->top == EMPTY)
    /*do nothing*/;
      else
    while (optor->top > EMPTY)
      if (top_tor(optor) == '(')
        pop(optor);
      else {
        era.nd = operate(opnd, optor);
        push(era, opnd);
      }
      era = pop(opnd);
      printf("\t%.8g\n", era.nd);
      break;
    case 'p':
      print_stack(opnd);
      getchar();
      break;
    case 'q':
      exit(0);
      break;
    default:
      printf("error: unknown command %s\n", s);
      break;
    }
  }
  return 0;
}

struct Op *create_stack(int max, enum Optype type)
{
  struct Op *op;

  op =(Op *) malloc(sizeof(*op));
  if (op == NULL)
    nullerr();

  op->era = (Era *)calloc(sizeof(union Era), max);
  if (op->era == NULL)
    nullerr();

  op->max = max;
  op->top = EMPTY;
  op->type = type;

  return op;
}

void
push(union Era era, struct Op *op)
{
  if (op->top >= op->max) {
    if (op->type == ND)
      printf("error: stack full, can't push %g\n", era.nd);
    else
      printf("error: stack full, can't push %c\n", era.tor);
  }
  else
    op->era[op->top++] = era;
}

union Era
pop(struct Op *op)
{
  if (op->top > EMPTY)
    return op->era[--op->top];
  else {
    printf("error: stack empty\n");
    if (op->type == ND)
      op->era[EMPTY].nd = 0.0;
    else
      op->era[EMPTY].tor = 0;
    return op->era[EMPTY];
  }
}

void nullerr(void)
{
  printf("not enough memory\n");
  exit(1);
}

int getop(char s[])    // [K&R] section 4.3
{
  int i, c;

  while ((s[0] = c = getchar()) == ' ' || c == '\t')
    /*do nothing*/;
  s[1] = '\0';
  if (!isdigit(c) && c != '.')
    return c;        // not a number
  i = 0;
  if (isdigit(c))    // collect integer part
    while (isdigit(s[++i] = c = getchar()))
      ;
  if (c == '.')        // collect fraction part
    while (isdigit(s[++i] = c = getchar()))
      /*do nothing*/;
  s[i] = '\0';
  if (c != EOF)
    ungetc(c, stdin);
  return NUMBER;
}

double operate(struct Op *opnd, struct Op *optor)
{
  union Era nd1, nd2, tor;

  nd2 = pop(opnd);
  nd1 = pop(opnd);
  tor = pop(optor);

  switch (tor.tor) {
  case '+':
    return nd1.nd + nd2.nd;
    break;
  case '-':
    return nd1.nd - nd2.nd;
    break;
  case '*':
    return nd1.nd * nd2.nd;
    break;
  case '/':
    return nd1.nd / nd2.nd;
    break;
  default:
    return 0.0;
    break;
  }
}

void print_stack(struct Op *op)
{
  int i;
  for (i = op->top; i > 0; i--)
    printf("%g\n", op->era[i].nd);
}

char top_tor(struct Op *op)
{
  return op->era[op->top-1].tor;    // after push, top plus one
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -