廢話不說,見代碼。
《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;
歡迎批評指正!