首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言實現表達式求值:支持加減乘除與括號的完整解析

     編輯:關於C語言

C 語言實現表達式求值:支持加減乘除與括號的完整解析

表達式求值是經典棧應用。本文先給出不含括號的版本,再擴展支持括號。核心思想:兩個棧——操作數棧、操作符棧,利用運算符優先級決定何時計算。

一、不含括號版本

數據結構

#define STACK_INIT_SIZE 100
typedef struct { char data[STACK_INIT_SIZE]; int top; } OptrStack; // 操作符棧
typedef struct { double data[STACK_INIT_SIZE]; int top; } OpndStack; // 操作數棧

關鍵函數

  • `Judge_optr(ch)`:返回運算符優先級(+ - → 1,* / → 2)。
  • `Operate(b, a, op)`:執行二元運算,注意順序(b op a)。
  • `Jsbds_operate(str[])`:主掃描邏輯。

掃描邏輯

  1. 讀到數字:解析完整數值(支持多位數),壓入操作數棧。
  2. 讀到運算符:
    • 若操作符棧為空或當前運算符優先級 > 棧頂優先級 → 直接入棧。
    • 否則:彈出兩操作數、彈出棧頂運算符、計算、結果壓入操作數棧,然後當前運算符入棧。
  3. 掃描結束:操作符棧不空時重複彈出計算,直到棧空。
  4. 操作數棧頂即最終結果。

二、支持括號版本(關鍵修改)

優先級調整

int Judge_optr(char op) {
    switch (op) {
        case '(': return 0;
        case '+': case '-': return 1;
        case '*': case '/': return 2;
        case ')': return 3;
    }
}

掃描邏輯變化

  • 遇到 `(`:視為最低優先級(0),無條件入棧(`|| str[i]=='('`)。
  • 遇到 `)`:直接壓入操作符棧(作為標記),隨後在最終清理階段處理。
  • 最終清理階段:若棧頂為 `)` 或 `(`,直接彈出丟棄;否常規計算。

關鍵代碼片段

// 掃描主循環中 case '(' '+' '-' 合並:
if ((!Empty_OptrStack(optr)) || (Judge_optr(str[i]) > Judge_optr(GetTop_OptrStack(optr, top))) || (str[i]=='('))
    Push_OptrStack(optr, str[i]);
else { /* 彈出計算 */ }

// case ')' :
Push_OptrStack(optr, str[i]); break;

// 最終清理:
while (Empty_OptrStack(optr)) {
    if (GetTop_OptrStack(optr, top) == ')' || GetTop_OptrStack(optr, top) == '(')
        top = Pop_OptrStack(optr, top); // 丟棄括號
    else { /* 彈出計算 */ }
}

完整代碼結構

完整代碼包含:棧初始化/判空/入棧/出棧/取頂、運算符判斷、運算執行、主掃描函數、main 測試。因篇幅限制,此處給出核心邏輯,完整可運行代碼請參考原文附件。

測試示例

輸入:(1+2)*3-4/2
輸出:該表達式的計算結果為:7

常見坑點提醒

  1. 運算符優先級比較時,`(` 入棧優先級最低,但棧中 `(` 不參與計算,遇 `)` 才清理。
  2. 除法除零檢查。
  3. 數字解析需支持多位數、小數(用 `atof`)。
  4. 棧溢出檢查(教學代碼常省略,工程必須加)。
  5. 輸入字符串可能含空格,需跳過。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved