C语言编写一个计算器(附全源代码)

简介: C语言编写一个计算器(附全源代码)

这个计算器其实是我老师布置的一个c语言大作业,捉摸着搞了那么久的东西不能浪费了吧,于是我分享下我的代码和大概思路

给个关注点个赞,后续我会分享更多我们学生党的作业问题


白嫖党们先看代码,我就先上上全代码,干!

前言:

为了达到目的,首先自学了栈:按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。其次查阅多方面资料结合所学知识进行编写而成。


(1)InitStack(S)初始化:初始化一个新的栈。


(2)Empty(S)栈的非空判断:若栈S不空,则返回TRUE;否则,返回 FALSE。


(3)Push(S,x)入栈:在栈S的顶部插入元素x,若栈满,则返回 FALSE;否则,返回TRUE。


(4)Pop(S)出栈:若栈S不空,则返回栈顶元素,并从栈顶中删除该元 素;否则,返回空元素NULL。


(5)GetTop(S)取栈顶元素:若栈S不空,则返回栈顶元素;否则返回 空元素NULL。


(6)SetEmpty(S)置栈空操作:置栈S为空栈。

(7) 常以top = -1表示空栈。


进栈(PUSH)算法

①若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);

②置TOP=TOP+1(栈指针加1,指向进栈地址);

③S(TOP)=X,结束(X为新进栈的元素)


退栈(POP)算法

①若TOP≤0,则给出下溢信息,作出错处理(退栈前先检查是否已为空栈,空则下溢;不空则作②);

②X=S(TOP),(退栈后的元素赋给X):

③TOP=TOP-1,结束(栈指针减1,指向栈顶)

(1)函数功能介绍及介绍:能够实现连续的运算,混合运算,基本上可以等同于手机上计算器。仅限于加减乘除的四则运算。(强调运算时的括号必须是英文版本的,否则运行会出错。写表达式也可以加上“=”和不加不影响运行结果,最终还是以回车进行结束得到结果)。如果能在visualc++运行,稍微调整一下,可以利用自带的功能设置一个界面,这样就可以完成跟手机自带那种计算器相同了。

加法运算:1+2回车可得3,连续运算1+2+3+4+5回车可得15

减法运算:1-2回车为-1,连续运算5-1-2回车得2

乘法:23回车6,连续运算23*4回车24


除法运算24/4回车6,24/2/2回车6、

混合运算:(5+2)*2回车14


(一)软件环境:Devc++

我用的这个软件哈,个人感觉这里功能简单,特别容易上手。看图说话,是不是很简单嘛,又不复杂。

1.png

(二)设计方案

根据自学所得栈进行数据和符号的存储再输出,先设立单独的数据栈符号栈,我们以top=-1为标准,判断其是否为空栈,当然也用到了学过的struct来构建栈,先把字符存进去再说,在里面我们要进行运算,然后再拿出来给我们看。于是我们就要四则运算,用switch四个case把加减乘除表达出来,这能进行简单的运算吧,那混合运算还带括号咋办,于是要用到判断优先级,加减,乘除分别同级,先左括号读到右括号我们要停止,这样就可以进行混合的运算了。后面我们经过调用前面设的函数想办法怎么把它输出来,我们就是要用到入栈顶什么的最后出栈,用个free(str)释放下内存打印出来得到结果。


(3)函数功能:

用到了第八章内容结构结合自学内容构造栈,switch表达式来判断优先级,主要用到的为自学的栈push进栈,pop出栈,top=-1划分是否为空字符,在前言写很清楚了。


(四)全代码:

#include<stdio.h>
#include<stdlib.h>
/*数据栈*/
struct shuju   //struct结构体构建栈 
{
  int data[100];
  int top;
};
/*符号栈*/ 
struct fuhao
 {
  char symbol[100];
  int top;
};
void InitOperateNum(struct shuju *StackNum)    //数据栈非空 
{
    StackNum->top = -1;
}
void InitOperateSymbol(struct fuhao *StackSymbol)    //符号栈非空 
{  
    StackSymbol->top = -1; 
}
/*存入数据栈*/
void Inshuju(struct shuju *StackNum, int num)
{
  StackNum->top ++;
  StackNum->data[StackNum->top] = num;
}
/*存入符号栈*/ 
void Infuhao(struct fuhao *StackSymbol, char ch)
{
  StackSymbol->top ++;
  StackSymbol->symbol[StackSymbol->top] = ch;
}
/*读取数据栈*/
int Randshuju(struct shuju *StackNum)
{
  return StackNum->data[StackNum->top];
}
/*读取符号栈*/
char Randfuhao(struct fuhao *StackSymbol)
{
  return StackSymbol->symbol[StackSymbol->top];
}
/*从数据栈取出数据*/
int Putshuju(struct shuju *StackNum)
{
  int x;
  x = StackNum->data[StackNum->top];
  StackNum->top --;
  return x;
}
/*从符号栈取出符号*/
char Putfuhao(struct fuhao *StackSymbol)
{
  char c;
  c = StackSymbol->symbol[StackSymbol->top];
  StackSymbol->top --;
  return c;
}
/*符号优先级判断*/
int judge(char ch) {
  if(ch == '(')
   {
    return 1; 
    }
  if(ch == '+' || ch == '-') {
    return 2;
  }
  else if(ch == '*' || ch == '/') {
    return 3;
  }
  else if(ch == ')') {
    return 4;
  }
}
/*四则运算*/
int Math(int v1, int v2, char c)
{
  int sum;
  switch(c) {
    case '+' : {
      sum = v1 + v2;
      break;
    }
    case '-' : {
      sum = v1 - v2;
      break;
    }
    case '*' : {
      sum = v1 * v2;
      break;
    } 
    case '/' : {
      sum = v1 / v2;
      break;
    }
  }
  return sum;
}
int main()
{
  struct shuju data;
  struct fuhao symbol;
  InitOperateNum(&data);   //调用数据 
  InitOperateSymbol(&symbol);  //调用符号 
  int i, t, sum, v1, v2;
  char c;
  i = t = sum = 0;
  char v[100] = {0};
  char *str = (char *)malloc(sizeof(char)*200);
  while((c = getchar()) != '\n')  //非空字符 
   {
    str[i] = c;
    i ++;
  }
  str[i] = '\0';
  for(i = 0; str[i] != '\0'; i ++) {
    if(i == 0 && str[i] == '-') {
      v[t++] = str[i];
    }
    else if(str[i] == '(' && str[i+1] == '-') {
      i ++;
      v[t++] = str[i++];
      while(str[i] >= '0' && str[i] <= '9') {
        v[t] = str[i];
        t ++;
        i ++;
      }
      Inshuju(&data, atoi(v));
      while(t > 0) {
        v[t] = 0;
        t --;
      }
      if(str[i] != ')') {
        i --;
        Infuhao(&symbol, '(');
      }
    }
    else if(str[i] >= '0' && str[i] <= '9') {
      while(str[i] >= '0' && str[i] <= '9') {
        v[t] = str[i];
        t ++;
        i ++;
      }
      Inshuju(&data, atoi(v));
      while(t > 0) {
        v[t] = 0;
        t --;
      }
      i --;
    }
    else {
      if(symbol.top == -1) 
      {        //如果符号栈没有元素,直接把符号放入符号栈 
        Infuhao(&symbol, str[i]);
      }
      else if(judge(str[i]) == 1) { //如果此符号是'(',直接放入符号栈 
        Infuhao(&symbol, str[i]);
      }
      else if(judge(str[i]) == 2) { //如果此符号是'+'或'-',判断与栈顶符号是优先级 
        if(judge(Randfuhao(&symbol)) == 1) { //如果栈顶符号是'(',放入符号栈 
          Infuhao(&symbol, str[i]);
        }
        else if(judge(Randfuhao(&symbol)) == 2) { //如果栈顶符号是'+'或'-',则出栈运算 
          while(symbol.top >= 0 && data.top >= 1) { //循环出栈
            v2 = Putshuju(&data);
            v1 = Putshuju(&data);
            sum = Math(v1, v2, Putfuhao(&symbol));
            Inshuju(&data, sum); //将运算结果压入数据栈 
          }
          Infuhao(&symbol, str[i]); //新符号进栈 
        }
        else if(judge(Randfuhao(&symbol)) == 3) { //如果栈顶符号是'*'或'/',则进符号栈 
          while(symbol.top >= 0 && data.top >= 1) { //循环出栈
            v2 = Putshuju(&data);
            v1 = Putshuju(&data);
            sum = Math(v1, v2, Putfuhao(&symbol));
            Inshuju(&data, sum); //将运算结果压入数据栈 
          }
          Infuhao(&symbol, str[i]); //新符号进栈 
        }
        /*栈顶符号不可能是')',故不做判断*/ 
      }
      else if(judge(str[i]) == 3) { //如果此符号是'*'或'/',则判断与栈顶符号是优先级
        if(judge(Randfuhao(&symbol)) == 1) { //如果栈顶符号是'(',放入符号栈 
          Infuhao(&symbol, str[i]);
        }
        else if(judge(Randfuhao(&symbol)) == 2) { //如果栈顶符号是'+'或'-',则进符号栈
          Infuhao(&symbol, str[i]); //新符号进栈
        }
        else if(judge(Randfuhao(&symbol)) == 3) { //如果栈顶符号是'*'或'/',则出栈运算 
          while(symbol.top >= 0 && data.top >= 1) { //循环出栈
            v2 = Putshuju(&data);
            v1 = Putshuju(&data);
            sum = Math(v1, v2, Putfuhao(&symbol));
            Inshuju(&data, sum); //将运算结果压入数据栈 
          }
          Infuhao(&symbol, str[i]); //新符号进栈
        }
      }
      else if(judge(str[i]) == 4) { // 如果此符号是')',则出栈运算直到遇到'('
        do { //循环出栈直到遇到'('
          v2 = Putshuju(&data);
          v1 = Putshuju(&data);
          sum = Math(v1, v2, Putfuhao(&symbol));
          Inshuju(&data, sum); //将运算结果压入数据栈 
        }while(judge(Randfuhao(&symbol)) != 1);
        Putfuhao(&symbol); //括号内运算结束后使'('出栈 
      }     
    }
  }
  free(str); //释放内存空间
  while(symbol.top != -1) {
    v2 = Putshuju(&data);
    v1 = Putshuju(&data);
    sum = Math(v1, v2, Putfuhao(&symbol));
    Inshuju(&data, sum);  
  }
  printf("%d", data.data[0]);
  return 0;
}

我们来看看演示结果:

1.png

1.png

1.png

好了,诸如类似不再演示了,代码讲解我觉得注释就够了,不关注点个赞吗?

相关文章
|
3月前
|
NoSQL 编译器 程序员
【C语言】揭秘GCC:从平凡到卓越的编译艺术,一场代码与效率的激情碰撞,探索那些不为人知的秘密武器,让你的程序瞬间提速百倍!
【8月更文挑战第20天】GCC,GNU Compiler Collection,是GNU项目中的开源编译器集合,支持C、C++等多种语言。作为C语言程序员的重要工具,GCC具备跨平台性、高度可配置性及丰富的优化选项等特点。通过简单示例,如编译“Hello, GCC!”程序 (`gcc -o hello hello.c`),展示了GCC的基础用法及不同优化级别(`-O0`, `-O1`, `-O3`)对性能的影响。GCC还支持生成调试信息(`-g`),便于使用GDB等工具进行调试。尽管有如Microsoft Visual C++、Clang等竞品,GCC仍因其灵活性和强大的功能被广泛采用。
127 1
|
3月前
|
存储 C语言
【C语言】基础刷题训练4(含全面分析和代码改进示例)
【C语言】基础刷题训练4(含全面分析和代码改进示例)
|
1月前
|
存储 搜索推荐 C语言
深入C语言指针,使代码更加灵活(二)
深入C语言指针,使代码更加灵活(二)
|
1月前
|
存储 程序员 编译器
深入C语言指针,使代码更加灵活(一)
深入C语言指针,使代码更加灵活(一)
|
1月前
|
C语言
深入C语言指针,使代码更加灵活(三)
深入C语言指针,使代码更加灵活(三)
深入C语言指针,使代码更加灵活(三)
|
2月前
|
安全 C语言
在C语言中,正确使用运算符能提升代码的可读性和效率
在C语言中,运算符的使用需要注意优先级、结合性、自增自减的形式、逻辑运算的短路特性、位运算的类型、条件运算的可读性、类型转换以及使用括号来明确运算顺序。掌握这些注意事项可以帮助编写出更安全和高效的代码。
50 4
|
1月前
|
C语言
C语言练习题代码
C语言练习题代码
|
2月前
|
存储 算法 C语言
数据结构基础详解(C语言):单链表_定义_初始化_插入_删除_查找_建立操作_纯c语言代码注释讲解
本文详细介绍了单链表的理论知识,涵盖单链表的定义、优点与缺点,并通过示例代码讲解了单链表的初始化、插入、删除、查找等核心操作。文中还具体分析了按位序插入、指定节点前后插入、按位序删除及按值查找等算法实现,并提供了尾插法和头插法建立单链表的方法,帮助读者深入理解单链表的基本原理与应用技巧。
545 6
|
2月前
|
存储 C语言 C++
数据结构基础详解(C语言) 顺序表:顺序表静态分配和动态分配增删改查基本操作的基本介绍及c语言代码实现
本文介绍了顺序表的定义及其在C/C++中的实现方法。顺序表通过连续存储空间实现线性表,使逻辑上相邻的元素在物理位置上也相邻。文章详细描述了静态分配与动态分配两种方式下的顺序表定义、初始化、插入、删除、查找等基本操作,并提供了具体代码示例。静态分配方式下顺序表的长度固定,而动态分配则可根据需求调整大小。此外,还总结了顺序表的优点,如随机访问效率高、存储密度大,以及缺点,如扩展不便和插入删除操作成本高等特点。
200 5
|
2月前
|
存储 C语言
数据结构基础详解(C语言): 栈与队列的详解附完整代码
栈是一种仅允许在一端进行插入和删除操作的线性表,常用于解决括号匹配、函数调用等问题。栈分为顺序栈和链栈,顺序栈使用数组存储,链栈基于单链表实现。栈的主要操作包括初始化、销毁、入栈、出栈等。栈的应用广泛,如表达式求值、递归等场景。栈的顺序存储结构由数组和栈顶指针构成,链栈则基于单链表的头插法实现。
390 3