回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

简易计算器2.0(c语言版本) 简单

头像 dfrwh 2025.03.09 104 2

把代码复制到mind+中上传模式的手动编辑里(arduino c)就能用了,有BUG欢迎评论。

使用方法:

A/B键左右切换,触摸键O选定,按等于输出结果,C清除。

 

WechatIMG10.jpg

 

#include
#include

// 变量定义
String             mind_s_ShuChuXianShi;
volatile int       mind_n_GeShu;  // 当前选择的位置
SimpleList mind_l_ShuChu; // 输入列表
volatile bool      inputProcessed = false;  // 防止重复输入

// 函数声明
void onButtonBPressed();
void pin15TouchCallback();
void onButtonAPressed();
void updateDisplay();
void calculateResult();
int getPriority(char op);
void computeTop(float numbers[], int &numTop, char operators[], int &opTop);
void handleInput(int selection);

// 主程序
void setup() {
   mPython.begin();
   buttonB.setPressedCallback(onButtonBPressed);
   touchPadO.setTouchedCallback(pin15TouchCallback);
   buttonA.setPressedCallback(onButtonAPressed);
   mPython.setTouchThreshold(70);

   mind_s_ShuChuXianShi = "";
   mind_n_GeShu = 1;
   updateDisplay();
}

void loop() {
   // 空循环
}

// 更新屏幕显示
void updateDisplay() {
   display.fillScreen(0);
   display.setCursorLine(1);
   display.printLine("   1  2  3  4  5  6  7  8  9");
   display.setCursorLine(2);
   display.printLine("   0  +  -  *  / (  )  =  c");
   display.rect(4, 35, 120, 23, false);

   // 计算并更新选择框位置
   int rectX = (mind_n_GeShu <= 9) ? ((mind_n_GeShu - 1) * 13) + 4 : ((mind_n_GeShu - 10) * 12.1) + 4;
   display.rect(rectX, 1 + ((mind_n_GeShu > 9) ? 17 : 0), 14, 14, false);

   // 显示输入内容
   display.setCursor(9, 38);
   for (int i = 0; i < mind_l_ShuChu.size(); i++) {
       display.print(mind_l_ShuChu[i]);
   }
}

// 按钮 B 事件(向右移动选择框)
void onButtonBPressed() {
   mind_n_GeShu = (mind_n_GeShu % 18) + 1; // 增加到18,支持更多按钮
   updateDisplay();
}

// 按钮 A 事件(向左移动选择框)
void onButtonAPressed() {
   mind_n_GeShu = (mind_n_GeShu - 2 + 18) % 18 + 1;
   updateDisplay();
}

// 触摸事件(确定输入)
void pin15TouchCallback() {
   // 确保每次触摸只处理一次输入
   if (inputProcessed) {
       return;
   }
   inputProcessed = true;  // 防止重复输入

   if (mind_l_ShuChu.size() >= 16) {
       inputProcessed = false;
       return;  // 超过输入限制,直接返回
   }

   handleInput(mind_n_GeShu);
   updateDisplay();
   inputProcessed = false;  // 处理完输入后允许下一次输入
}

// 处理输入
void handleInput(int selection) {
   String lastInput = (mind_l_ShuChu.size() > 0) ? mind_l_ShuChu[mind_l_ShuChu.size() - 1] : "";

   // 禁止首个输入为运算符或右括号
   if (mind_l_ShuChu.size() == 0 && (selection >= 11 && selection <= 14 || selection == 16)) {
       return;
   }

   // 禁止连续输入运算符
   if ((selection == 11 || selection == 12 || selection == 13 || selection == 14) && 
       (lastInput == "+" || lastInput == "-" || lastInput == "*" || lastInput == "/")) {
       return;
   }

   // 处理括号
   if (selection == 15) {  // 左括号
       mind_l_ShuChu.push_back("(");
   } else if (selection == 16) {  // 右括号
       mind_l_ShuChu.push_back(")");
   } else if (selection >= 1 && selection <= 9) {  // 数字
       mind_l_ShuChu.push_back(String(selection));
   } else if (selection == 10) {  // 数字0
       mind_l_ShuChu.push_back("0");
   } else if (selection == 11) {  // 运算符 +
       mind_l_ShuChu.push_back("+");
   } else if (selection == 12) {  // 运算符 -
       mind_l_ShuChu.push_back("-");
   } else if (selection == 13) {  // 运算符 *
       mind_l_ShuChu.push_back("*");
   } else if (selection == 14) {  // 运算符 /
       mind_l_ShuChu.push_back("/");
   } else if (selection == 17) {  // 等号 = 
       calculateResult();
   } else if (selection == 18) {  // 清除 c
       mind_l_ShuChu.clear();
   }
   updateDisplay();
}

// 计算表达式结果
void calculateResult() {
   if (mind_l_ShuChu.size() == 0) {
       mind_l_ShuChu.push_back("错误: 输入为空");
       updateDisplay();
       return;
   }

   const int MAX_SIZE = 16;
   float numbers[MAX_SIZE];  // 存放数字
   char operators[MAX_SIZE]; // 存放运算符
   int numTop = -1, opTop = -1; // 栈指针

   String expression = "";
   for (int i = 0; i < mind_l_ShuChu.size(); i++) {
       expression += mind_l_ShuChu[i];
   }

   // 解析表达式
   for (int i = 0; i < expression.length(); i++) {
       char c = expression[i];

       if (isdigit(c)) {
           // 处理数字
           numbers[++numTop] = c - '0';
       } else if (c == '(') {
           // 处理左括号
           operators[++opTop] = c;
       } else if (c == ')') {
           // 处理右括号
           while (opTop >= 0 && operators[opTop] != '(') {
               computeTop(numbers, numTop, operators, opTop);
           }
           opTop--;  // 弹出左括号
       } else if (c == '+' || c == '-' || c == '*' || c == '/') {
           // 处理运算符
           while (opTop >= 0 && getPriority(operators[opTop]) >= getPriority(c)) {
               computeTop(numbers, numTop, operators, opTop);
           }
           operators[++opTop] = c;
       }
   }

   // 处理栈中剩余的运算符
   while (opTop >= 0) {
       computeTop(numbers, numTop, operators, opTop);
   }

   if (numTop < 0) {
       mind_l_ShuChu.clear();
       mind_l_ShuChu.push_back("错误");
   } else {
       mind_l_ShuChu.clear();
       mind_l_ShuChu.push_back(String(numbers[numTop], 2));  // 显示 2 位小数
   }
   updateDisplay();
}

// 获取运算符优先级
int getPriority(char op) {
   if (op == '+' || op == '-') return 1;
   if (op == '*' || op == '/') return 2;
   return 0;
}

// 计算栈顶运算
void computeTop(float numbers[], int &numTop, char operators[], int &opTop) {
   if (numTop < 1 || opTop < 0) return;

   float b = numbers[numTop--];
   float a = numbers[numTop--];
   char op = operators[opTop--];

   float result = 0;
   if (op == '+') result = a + b;
   else if (op == '-') result = a - b;
   else if (op == '*') result = a * b;
   else if (op == '/') {
       if (b == 0) {
           mind_l_ShuChu.clear();
           mind_l_ShuChu.push_back("错误");
           return;
       }
       result = a / b;
   }

   numbers[++numTop] = result;  // 更新栈
}

评论

user-avatar
  • woshitiger

    woshitiger2025.05.03

    我通过了全国计算机二级C语言考试,拿到了合格证书,但看起来还是不太懂。

    1
    • dfrwh

      dfrwh2025.05.04

      这样呢 #include &lt;MPython.h&gt; // 掌控板核心库 #include &lt;SimpleList.h&gt; // 动态数组(链表)库,用于存储输入内容 // ========== 全局变量定义 ========== String mind_s_ShuChuXianShi; // 屏幕输出显示字符串(暂未使用) volatile int mind_n_GeShu; // 当前选中的按钮编号(1~18) SimpleList&lt;String&gt; mind_l_ShuChu; // 存储用户逐个输入的表达式内容 volatile bool inputProcessed = false; // 防止触摸重复触发的标志位 // ========== 函数声明 ========== void onButtonBPressed(); // 按钮 B 按下回调 void pin15TouchCallback(); // 触摸引脚回调(输入确认) void onButtonAPressed(); // 按钮 A 按下回调 void updateDisplay(); // 更新 OLED 屏幕显示内容 void calculateResult(); // 计算表达式的结果 int getPriority(char op); // 获取运算符优先级 void computeTop(float numbers[], int &amp;numTop, char operators[], int &amp;opTop); // 计算栈顶运算 void handleInput(int selection); // 根据选择处理输入内容 // ========== 初始化函数 ========== void setup() { mPython.begin(); // 初始化掌控板 // 设置按钮和触摸回调函数 buttonB.setPressedCallback(onButtonBPressed); touchPadO.setTouchedCallback(pin15TouchCallback); buttonA.setPressedCallback(onButtonAPressed); mPython.setTouchThreshold(70); // 设置触摸灵敏度阈值 // 初始化状态 mind_s_ShuChuXianShi = &quot;&quot;; mind_n_GeShu = 1; updateDisplay(); // 初次更新显示 } // ========== 主循环 ========== void loop() { // 主循环中不需要持续处理,由回调完成操作 } // ========== 更新 OLED 显示 ========== void updateDisplay() { display.fillScreen(0); // 清空屏幕 display.setCursorLine(1); display.printLine(&quot; 1 2 3 4 5 6 7 8 9&quot;); // 第一行:数字 1~9 display.setCursorLine(2); display.printLine(&quot; 0 + - * / ( ) = c&quot;); // 第二行:运算符和括号 display.rect(4, 35, 120, 23, false); // 绘制输入区域框 // 计算选择框的 x 坐标位置(1~9 为第一行,10~18 为第二行) int rectX = (mind_n_GeShu &lt;= 9) ? ((mind_n_GeShu - 1) * 13) + 4 : ((mind_n_GeShu - 10) * 12.1) + 4; display.rect(rectX, 1 + ((mind_n_GeShu &gt; 9) ? 17 : 0), 14, 14, false); // 绘制选择框 // 显示输入的内容 display.setCursor(9, 38); // 输入框左上角位置 for (int i = 0; i &lt; mind_l_ShuChu.size(); i++) { display.print(mind_l_ShuChu[i]); // 逐个显示输入 } } // ========== 按钮 B 事件 ========== void onButtonBPressed() { mind_n_GeShu = (mind_n_GeShu % 18) + 1; // 向右移动选择框,循环到 1~18 updateDisplay(); // 更新显示 } // ========== 按钮 A 事件 ========== void onButtonAPressed() { mind_n_GeShu = (mind_n_GeShu - 2 + 18) % 18 + 1; // 向左移动选择框 updateDisplay(); } // ========== 触摸事件:确认选择 ========== void pin15TouchCallback() { if (inputProcessed) return; // 防止重复处理 inputProcessed = true; if (mind_l_ShuChu.size() &gt;= 16) { // 限制最大输入长度 inputProcessed = false; return; } handleInput(mind_n_GeShu); // 根据当前按钮处理输入 updateDisplay(); // 更新显示 inputProcessed = false; } // ========== 处理按键输入内容 ========== void handleInput(int selection) { String lastInput = (mind_l_ShuChu.size() &gt; 0) ? mind_l_ShuChu[mind_l_ShuChu.size() - 1] : &quot;&quot;; // 禁止以符号或右括号开头 if (mind_l_ShuChu.size() == 0 &amp;&amp; (selection &gt;= 11 &amp;&amp; selection &lt;= 14 || selection == 16)) return; // 禁止连续两个符号 if ((selection &gt;= 11 &amp;&amp; selection &lt;= 14) &amp;&amp; (lastInput == &quot;+&quot; || lastInput == &quot;-&quot; || lastInput == &quot;*&quot; || lastInput == &quot;/&quot;)) return; // 按选择编号执行不同操作 if (selection == 15) mind_l_ShuChu.push_back(&quot;(&quot;); // 左括号 else if (selection == 16) mind_l_ShuChu.push_back(&quot;)&quot;); // 右括号 else if (selection &gt;= 1 &amp;&amp; selection &lt;= 9) mind_l_ShuChu.push_back(String(selection)); // 数字 1~9 else if (selection == 10) mind_l_ShuChu.push_back(&quot;0&quot;); // 数字 0 else if (selection == 11) mind_l_ShuChu.push_back(&quot;+&quot;); else if (selection == 12) mind_l_ShuChu.push_back(&quot;-&quot;); else if (selection == 13) mind_l_ShuChu.push_back(&quot;*&quot;); else if (selection == 14) mind_l_ShuChu.push_back(&quot;/&quot;); else if (selection == 17) calculateResult(); // = 执行计算 else if (selection == 18) mind_l_ShuChu.clear(); // c 清空 updateDisplay(); } // ========== 计算表达式结果 ========== void calculateResult() { if (mind_l_ShuChu.size() == 0) { mind_l_ShuChu.push_back(&quot;错误: 输入为空&quot;); updateDisplay(); return; } const int MAX_SIZE = 16; float numbers[MAX_SIZE]; // 数字栈 char operators[MAX_SIZE]; // 运算符栈 int numTop = -1, opTop = -1; // 栈顶指针 String expression = &quot;&quot;; for (int i = 0; i &lt; mind_l_ShuChu.size(); i++) { expression += mind_l_ShuChu[i]; } // 遍历表达式每个字符 for (int i = 0; i &lt; expression.length(); i++) { char c = expression[i]; if (isdigit(c)) { numbers[++numTop] = c - '0'; // 字符转数字后入数字栈 } else if (c == '(') { operators[++opTop] = c; // 左括号入栈 } else if (c == ')') { while (opTop &gt;= 0 &amp;&amp; operators[opTop] != '(') { computeTop(numbers, numTop, operators, opTop); // 处理括号内表达式 } opTop--; // 弹出左括号 } else if (c == '+' || c == '-' || c == '*' || c == '/') { // 比较优先级,处理高优先级运算 while (opTop &gt;= 0 &amp;&amp; getPriority(operators[opTop]) &gt;= getPriority(c)) { computeTop(numbers, numTop, operators, opTop); } operators[++opTop] = c; // 当前运算符入栈 } } // 处理剩余运算符 while (opTop &gt;= 0) { computeTop(numbers, numTop, operators, opTop); } // 输出结果 mind_l_ShuChu.clear(); if (numTop &lt; 0) { mind_l_ShuChu.push_back(&quot;错误&quot;); } else { mind_l_ShuChu.push_back(String(numbers[numTop], 2)); // 保留两位小数 } updateDisplay(); } // ========== 获取运算符优先级 ========== int getPriority(char op) { if (op == '+' || op == '-') return 1; if (op == '*' || op == '/') return 2; return 0; } // ========== 计算栈顶运算 ========== void computeTop(float numbers[], int &amp;numTop, char operators[], int &amp;opTop) { if (numTop &lt; 1 || opTop &lt; 0) return; // 不足两个数字或无运算符 float b = numbers[numTop--]; // 取出操作数 b float a = numbers[numTop--]; // 取出操作数 a char op = operators[opTop--]; // 取出运算符 float result = 0; if (op == '+') result = a + b; else if (op == '-') result = a - b; else if (op == '*') result = a * b; else if (op == '/') { if (b == 0) { // 除以零报错 mind_l_ShuChu.clear(); mind_l_ShuChu.push_back(&quot;错误&quot;); return; } result = a / b; } numbers[++numTop] = result; // 将结果压回数字栈 }