C语言实现简单计算器程序

这两天在看一个C语言写的计算器程序,做了不少的功夫,跟着作者一步步的进行完善,了解了许多细节性的东西,在此自己做个总结,加深自己对程序的印象,也算是梳理。

在该计算器程序,能进行加减乘除、sin、cos、exp等操作,同时能进行数值保存功能。而该计算器使用逆波兰表示法。即所有运算符都跟在操作数的后面,比如下列表达式:
(1 - 2) * (4 + 5)采用逆波兰表示法表示为:1 2 - 4 5 + *
逆波兰表达法中不需要圆括号,只要知道每个运算符需要几个操作数就不会引起歧义。

计算器程序实现很简单,具体原理如下:

while(/* 下一个运算符或操作数不是文件结束指示符 */)
  if(/* 是数 */)
    /* 将该数压入到栈中 */
  else if (/* 是运算符 */)
    /* 弹出所需数目的操作数 */
    /* 执行运算 */
    /* 将结果压入到栈中 */
  else if (/* 是换行符 */)
    /* 弹出并打印栈顶的值 */
  else
    /* 出错 */

在程序设计中,使用模块化思想,getop函数来进行读入,该函数返回一个标识,用来标识读入的是什么类型。主循环体中根据该标识执行相应的动作。

以下是该程序: (我将所有函数和变量放在同一文件)

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

#define MAXOP 100
#define NUMBER '0'  //标识读入的是数字
#define NAME 'n'   //标识读入的是字符串(函数名或非法字符串)
#define ALPHA 26
int getop(char []);
void push (double); //压栈
double pop(void);  //出栈
void clear(void);  //清空栈
void mathfnc(char []);  //执行相应的数学函数sin、cos、exp等

int main(void)
{
  int type;
  int i, var = 0;
  double op1, op2,v;
  char s[MAXOP];
  double variable[ALPHA];

  for (i = 0; i < ALPHA; i++)  //初始化用于保存数值的变量数组
    variable[i] = 0.0;

  while ((type = getop(s)) != EOF)  //读取输入
  {
    switch (type)
    {
      case NUMBER:
        push (atof(s));
        break;
      case NAME:
        mathfnc(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 '%':
        op2 = pop();
        if (op2 != 0.0)
          push (fmod(pop(), op2));
        else
          printf ("error: zero divisor\n");
        break;
      case '?':  //打印栈顶元素
        op2 = pop();
        printf ("\t%.8g\n", op2);
        push (op2);
        break;
      case '=':  //保存数值
        pop();
        if (var >= 'A' && var <= 'Z')
          variable[var - 'A'] = pop();
        else
          printf ("error: no variable name\n");
        break;
      case 'c':
        clear();
        break;
      case 'd':  //复制栈顶元素
        op2 = pop();
        push(op2);
        push(op2);
        break;
      case 's':  //交换栈元素
        op1 = pop();
        op2 = pop();
        push(op1);
        push(op2);
      case '\n':
        v = pop();  //v保存最后的一次结果
        printf ("\t%.8g\n", v);
        break;
      default:
        if (type >= 'A' && type <= 'Z')
          push(variable[type - 'A']);
        else if (type == '@')  //输入的字符@表示最近一次结果值
          push(v);
        else
          printf ("error: unknown command %s\n", s);
        break;
    }
    var = type;
  }
  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: statck empty\n");
    return 0.0;
  }
}

void clear(void)
{
  sp = 0;
}

void mathfnc (char s[])
{
  double op2;

  if (strcmp (s, "sin") == 0)
    push(sin(pop()));
  else if(strcmp (s, "cos") == 0)
    push(cos(pop()));
  else if(strcmp (s, "exp") == 0)
    push(exp(pop()));
  else if(strcmp (s, "pow") == 0)
  {
    op2 = pop();
    push (pow(pop(), op2));
  }
  else
    printf ("error: %s not supported\n", s);
}

/* ----------------------------------------------------------- */

#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';

  i = 0;

  if (islower(c))  //判断是否为小写字母,也即读取由小写字母组成的字符串
  {
    while (islower(s[++i] = c = getch()))
      ;
    s[i] = '\0';

    if (c != EOF)
      ungetch(c);
    if (strlen (s) > 1)
      return NAME;
    else
      return c;
  }

  if (!isdigit(c) && c != '.' && c != '-')
    return c;

  if (c == '-')   //用于判断是负数还是减操作
  {
    if (isdigit(c = getch()) || c == '.')
      s[++i] = c;
    else
    {
      if (c != EOF)
        ungetch(c);
      return '-';
    }
  }

  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;
}

该程序虽然简单,但是还是存在一些小小的问题,比如没有数据时进行pop的话,会打印栈中无数据同时返回数值0.0,在循环体中许多执行操作会将该数值保存到栈中,之后打印该值,用户体验度比较差。程序设计方面,模块化设计使得该程序容易增加功能而不影响其他模块,比如增加一些数学函数处理,在mathfnc函数中去添加,或增加一些运算符操作,可以在主循环体中增加。

总之,这次学习还是颇有收获。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C语言实现简单计算器功能(1)

    本文为大家分享了C语言实现简单计算器功能的具体方法,供大家参考,具体内容如下 这几天一直上控制语句,在学完if.switch和循环语句后,为了巩固所学知识点,想给学生出一道简单的计算器程序.题目如下: 通过所学的知识(选择语句.循环语句)完成一个简单的计算器编程,要求不许抄袭,只能用自己所学的知识点,不可引用网上自己的不懂的程序. 要求的格式如下图: 要求以这样的一种格式进行输出,并能通过选择完成不同的功能. 如:选择1,完成整数相加功能,算完后又能回到该页面. 经过分析,我简单的写了一段代码,

  • C语言结课设计之计算器功能

    本文实例为大家分享了C语言实现计算器的具体代码,供大家参考,具体内容如下 /*===============================================*\ ** 设计目的:简单计算器,计算形如10*(20.2-30.6)+5.0/2的表达式值 ** 简要原理:中缀式转逆波兰式(后缀式) ** IDE:Dev-Cpp 4.9.9.2 ** 注意事项:括号必须是英文状态的 ** 时间: 2014-6-17 \*==================================

  • C语言实现简单计算器功能(2)

    本文接着上一篇C语言实现简单计算器功能(1)继续学习. 之前用switch语句完成了一个简单计算器的功能,下面我给大家用if语句和while循环语句再实现一个简单计算器的编程. 要求: 实现简单的计算器,具体代码如下: #include <stdio.h> // 头文件 void main() { char a = 0; // 变量声明并初始化 int x, y; // 变量声明 int result = 0; char b = 37; while(1) // whiel循环实现反复在计算器系

  • C语言数据结构之简易计算器

    本文实例为大家分享了C语言简易计算器的具体代码,供大家参考,具体内容如下 主要解决了处理负数.小数等的基础运算操作,无图形界面 #include <iostream> #include <stack> using namespace std; class Calculator{ private: int Priority(char fuhao); double CalSuffix(string PostfixExp); public: double Calculate(string

  • C语言实现简单计算器程序

    这两天在看一个C语言写的计算器程序,做了不少的功夫,跟着作者一步步的进行完善,了解了许多细节性的东西,在此自己做个总结,加深自己对程序的印象,也算是梳理. 在该计算器程序,能进行加减乘除.sin.cos.exp等操作,同时能进行数值保存功能.而该计算器使用逆波兰表示法.即所有运算符都跟在操作数的后面,比如下列表达式: (1 - 2) * (4 + 5)采用逆波兰表示法表示为:1 2 - 4 5 + * 逆波兰表达法中不需要圆括号,只要知道每个运算符需要几个操作数就不会引起歧义. 计算器程序实现很

  • C语言实现简单计算器

    本文实例为大家分享了C语言实现简单计算器的具体代码,供大家参考,具体内容如下 实现效果如图: 实现代码如下: #include<stdio.h> #include<windows.h>//gotoxy #include<conio.h> #define width 80 #define height 30 void gotoxy(int x, int y); void GreateFrame() { int i = 0; for (i = 0 ; i < widt

  • C语言实现简单的计算器

    本文实例为大家分享了C语言实现简单计算器的具体代码,供大家参考,具体内容如下 描述:简单的实现四则运算 1.switch法 #include<stdio.h> void menu()//菜单函数 { printf("************************************\n"); printf("***** 1.add 2.sub *****\n"); printf("***** 3.mul 4.div *****\n&quo

  • PHP实现简单计算器小程序

    最近刚开始学习一门新的语言 PHP,然后就写了一个计算器的小程序,大体上的思路就是有一个前台程序和一个后台程序,前台程序就是界面类似下图这样的: 然后还有一个后台程序,就是负责计算的,那么根据这个就来设计页面,基本上就是 HTML 的知识,首先添加一个 table,然后添加一个表单,这个表单就提交给当前的页面(当然也可以传给别的页面),剩下的也就没有什么问题了,其实个例子说明 PHP既可以作前台的事情,也可以干后台的事情. Code: <?php /** * Created by PhpStor

  • 用C语言实现简单的计算器功能

    本文实例为大家分享了C语言实现简单的计算器功能的具体代码,供大家参考,具体内容如下 简单计算器,实现简单的加减乘除功能,选择对应的运算符输出运算符对应的编号,然后输入我们要计算的两个数,程序会给出计算结果. 效果演示 简单计算器代码 /* 简单计算器 name:zsh  */  #include <stdio.h>    //简单计算器  void menu()    //运算符显示界面  {     printf("---------------------------------

  • go语言简单网络程序实例分析

    本文实例分析了go语言简单网络程序.分享给大家供大家参考.具体分析如下: 服务端代码如下: 复制代码 代码如下: package main import (     "net"     "os" ) func serve(s net.Conn) {     var buf [1024]byte     for {         n, err := s.Read(&buf)         if err != nil || n == 0 {         

  • java 简单的计算器程序实例代码

    java 简单的计算器程序 实现实例: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Calculator { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { CalculatorFrame frame = new Calculato

  • c++编写简单的计算器程序

    首先来看下本人的开发环境 系统:win7 电脑:dell 运行环境:vs2015 语言:c++ 简单计算器代码 //四则运算 #include "stdafx.h" #include<iostream> #include<stdio.h> using namespace std; void add() { printf("输入要计算的加数(例如a b)\n"); int adda=0, addb=0,addc=0; cin >>

随机推荐