天天看點

四則運算表達式求值程式(C語言版)

廢話不說,見代碼。

《Compute.h》頭檔案

#include <stdio.h> 

#include <string.h> 

#include <stdlib.h> 

/*以下為本程式涉及到的函數的聲明*/

int CheckString(const char *Str);   /*檢查字元串中有否除了0-9,+,-,*,/,(,),之外的其他字元*/

void  DealString(char *OperatorArr, double *DigitalArr, int CurrPosition); /*将目前已經完成運算的運算符消去,同時将數值數組的位置調整以進行下一次運算。*/

double DealNumber(const char *Str);  /*對于輸入的字元串,先将其小數點以前的部分複制到tempStr[]數組中*/

double ComputeString(const char *Str); /*對輸入的字元串進行處理,是本程式最重要的一個函數*/

《Compute.c》函數實作程式

#include <stdio.h>   

#include <stdlib.h>  

#include "Compute.h"

/*以下為本程式中各函數的實作*/

/**************************************************************************

* 函數名:  int CheckString(char *Str)

* 輸入參數:char *Str: 輸入的字元串

* 傳回參數:

            0:字元串中有不符合規定的字元

            1: 字元串字元符合規定,沒有不符合規定的字元.

* 功能:

            檢查字元串中有否除了0-9,+,-,*,/,(,),之外的其他字元,

            如果有,則傳回0, 表示出現錯誤。

            若沒有,則傳回1,表式字元串符合規定。

**************************************************************************/

int CheckString(const char *Str)

{

int iFlag         = 0;      //k用于檢查括号是否配對

int iCharacterNum = 0;      //iCharacterNum用于統計輸入的字元的個數

    while ((*Str) != '\0')

if (((*Str)>='0' && (*Str)<='9') || ((*Str)=='+') || 

           ((*Str)=='-') || ((*Str)=='*') || ((*Str)=='/') || 

           ((*Str)=='.') || ((*Str)=='(') ||  ((*Str)==')') )

iCharacterNum ++;

}

else

printf("Input error, there have the char not the math expression char!\n");

return 0;

if ((*Str) == '(')

iFlag++;

else if ((*Str) ==')')

iFlag--;

Str++;

if (iFlag != 0)

printf("Input error, there is not have correct bracket '()'!\n");

printf("You input %d characters in total!\n", iCharacterNum);

return 1;

/*****************************************************************************************************************

* 函數名: void  DealString(char *OperatorArr, double *DigitalArr, int CurrPosition) 

* 輸入參數:

           char *OperatorArr :  運算符數組

           double *DigitalArr:  數值數組

           int CurrPosition:    目前運算符數組位置

* 傳回參數:無

           将目前已經完成運算的運算符消去,同時将數值數組的位置調整以進行下一次運算。

           傳入值CurrPosition若為3,則目前符号的數組位置為3.

           OperatorArr[3]=OperatorArr[3+1].......OperatorArr[len-2]=OperatorArr[len-1]  OperatorArr[len-1]='\0';

           DigitalArr[i]=DigitalArr[i+1].......DigitalArr[len-1]=DigitalArr[len]  因為數值比運算符多一個。

******************************************************************************************************************/

void  DealString(char *OperatorArr, double *DigitalArr, int CurrPosition)  

int iFlag = 0;

int iOperatorArrLen = strlen(OperatorArr);

for (iFlag = CurrPosition; iFlag < iOperatorArrLen; iFlag ++)   /*将已經運算過的符号,空出來的位置用後面的符号來填充,即把乘和除号的位置用後面的加和減号填充*/      

{   

OperatorArr[iFlag] = OperatorArr[iFlag+1];

DigitalArr[iFlag] = DigitalArr[iFlag+1];

    OperatorArr[iOperatorArrLen-1] = '\0';

/************************************************************************************

* 函數名:  double DealNumber(char *Str)

* 輸入參數:char *Str :由數字和小數點組成的字元,用以轉換成double型的數值。

* 傳回參數:dValueReturn:傳回轉換好的值。

            對于輸入的字元串,先将其小數點以前的部分複制到tempStr[]數組中,

            若有小數點,則将将小數點之後的數值,也就是小數部分先進行計算,值存入dValueReturn中

            計算完成後,再對整數部分進行計算,值加上小數部分的值,存入dValueReturn中。

*************************************************************************************/

double DealNumber(const char *Str)

double dValueReturn = 0.0;

double dFlag = 1.0;

int    iLoop = 0;

int    iFloat = 0;

int    iStrLen = 0;

char   tempStr[100] = {0};

    int    iTempi = 0;

    int    iStart = 0;

    int    iFlag = 1;            /*正負符号訓示器,若為1則為正數,為-1,此數為負數*/

    iStrLen = strlen(Str);

    if (Str[0] == '-')

iStart = 1;

        iFlag = -1;

    for (iLoop = iStart; iLoop < iStrLen; iLoop ++)

        if (Str[iLoop] == '.') 

            iFloat = iLoop;

            break;

        tempStr[iTempi++] = Str[iLoop];  /*将整數部分複制到tempStr[]中*/

    tempStr[iTempi] = '\0';

    if (iFloat != 0)

for (iLoop = iFloat+1; iLoop < iStrLen; iLoop ++) /*将小數部分計算出來*/

if (Str[iLoop] == '.')  /*如果有多餘的小數點,則表示輸入錯誤*/

printf("There is more that one dot '.' in number!error!!!\n");

exit(0);

            dFlag = dFlag * 0.1;

            dValueReturn += (dFlag * (Str[iLoop]-48));

    dFlag = 1.0;

    iStrLen = strlen(tempStr);           /*計算整數部分*/

    for (iLoop = iStrLen-1; iLoop >= 0; iLoop --)

dValueReturn = dValueReturn + (dFlag * (tempStr[iLoop] - 48));

        dFlag *= 10;

    dValueReturn = dValueReturn * iFlag;

    return dValueReturn;

* 函數名: double ComputeString(char *Str)

           char *Str: 即将進行運算的字元串型數學表達式,如3.5+(2*3/5)

           dTotalNum[0]:計算結果将放入dTotalNum[0]中

           将輸入的字元串中的數字分别調用DealNumber(char *Str)函數進行數值變換,再将其依

           次存入doulbe dTotalNum[i]中,将加減乘除運算符依次存入字元串符号數組中,

           然後如果遇到括号,則将括号内的字元串存入另一字元數組中,然後用此

           ComputeString(char *Str) 遞歸函數進行遞歸運算。 然後根據先乘除,後加減的順序對已

           存入數組的數值根 據存入字元串符号數組的運算符進行運算。結果存入dTotalNum[0]中。

           傳回最終結果。

double ComputeString(const char *Str)           /*可遞歸函數*/

{                                /*取得數值字元串,并調用DealNumber轉換成double*/

char cStr[100] = {'\0'}, cTotalChar[30] = {'\0'};   /*cStr儲存目前的表達式串,cTotalChar儲存一個數的所有字元*/

    char cStack[80] = {'\0'};                  /*儲存所有的符号的堆棧*/

    int iCharPos = 0;                   /*儲存符号的位置指針*/

    double dTotalNum[80] = {0.0};     /*儲存目前所有的數的一個堆棧*/

    int iDigitalPos = 0;              /*儲存數字位置指針*/

    int iBracketFlag = 0;             /*若iBracketFlag=1則表示有一對括号*/

    int iCharInBracketNum = 0, iCharInNumberNum = 0;  /*iCharInBracketNum儲存新括号内的字元數, iCharInNumberNum儲存number裡的字元位置*/

    int iNumOfMulAndDiv = 0;                         /*乘除符号數量*/

    int iNumOfAddAndDec = 0;                         /*加減符号數量*/

    while ((*Str) != '\0')           /*當p==1 和k==0時,表示已經把括号裡的内容全部複制到g[100]中了*/

iBracketFlag = 0;

        iCharInBracketNum = 0;

switch (*Str)

case '+':            /*目前字元為加減乘除時則表示*/

case '-':

case '*':

case '/':

cStack[iCharPos++] = (*Str);

            if(((*Str) == '*') || ((*Str) == '/'))

iNumOfMulAndDiv ++;

iNumOfAddAndDec ++;

            if((*(Str-1)) != ')')

cTotalChar[iCharInNumberNum] = '\0';

iCharInNumberNum = 0;             /*完成一個數字的複制,其位置指針i=0*/

dTotalNum[iDigitalPos++] = DealNumber(cTotalChar);

        case '(':   /*有括号,則将目前括号作用範圍内的全部字元儲存,作為*/

{           /*一個新的字元表達式進行遞歸調用ComputeString函數計算。*/

iBracketFlag ++;            

            while(iBracketFlag > 0)

Str ++;

cStr[iCharInBracketNum] = (*Str);

iCharInBracketNum ++;

if((*Str) == ')')

iBracketFlag--;

                else if((*Str) == '(')

iBracketFlag ++;

            cStr[iCharInBracketNum-1] = '\0';

            iCharInBracketNum = 0;         /*完成一個括号内容的複制,其位置指針num=0*/

            dTotalNum[iDigitalPos++] = ComputeString(cStr);

        default:

cTotalChar[iCharInNumberNum++] = (*Str);

if((*(Str+1)) == '\0')

                dTotalNum[iDigitalPos++] = DealNumber(cTotalChar);

        Str ++;

    cStack[iCharPos] = '\0';

    iCharInNumberNum = 0;

    while (iNumOfMulAndDiv > 0)

   switch (cStack[iCharInNumberNum])

case '*': 

   iNumOfMulAndDiv --;

            dTotalNum[iCharInNumberNum+1] = dTotalNum[iCharInNumberNum] * dTotalNum[iCharInNumberNum+1];

            DealString(cStack,dTotalNum, iCharInNumberNum);

        case '/': 

iNumOfMulAndDiv --;

            dTotalNum[iCharInNumberNum+1] = dTotalNum[iCharInNumberNum] / (float)dTotalNum[iCharInNumberNum+1];

            DealString(cStack, dTotalNum, iCharInNumberNum);

   iCharInNumberNum ++;

    while (iNumOfAddAndDec > 0)

switch(cStack[iCharInNumberNum])

case '+': 

dTotalNum[iCharInNumberNum+1] = dTotalNum[iCharInNumberNum] + dTotalNum[iCharInNumberNum+1];

            iNumOfAddAndDec --;

        case '-': 

dTotalNum[iCharInNumberNum+1] = dTotalNum[iCharInNumberNum] - dTotalNum[iCharInNumberNum+1];

            DealString(cStack,dTotalNum,iCharInNumberNum);

printf("operator error!");

    return dTotalNum[0];

《main.c》主程式

#include <stdio.h>  

#include <string.h>  

* 函數名: int main()

* 功能:   調用四則運算函數。

int main()

char cStr[100] = {'\0'};

    double dResult = 0.0;

    int iFlag = 1;

while (1)

printf("Enter expression(If you want to terminate the program, please enter '#' to end the program): \n");

        scanf("%s", cStr);

        iFlag = strncmp(cStr, "#", 1);

        if (iFlag == 0)

break;

        iFlag = CheckString(cStr);

continue;

dResult = ComputeString(cStr);

printf("%s = %f", cStr, dResult);

printf("\n");

    printf("Good bye!\n");

    return 0;

歡迎批評指正!

繼續閱讀