里面是我平常寫的計算器代碼
是上個假期不值得作業
運行沒啥問題
也有注釋
沒有啥特別的希望可以幫助大家
單片機源程序如下:
- include <stdio.h>
- #include <stdlib.h>
- #define LEN 100
- #define FLOAT 30///這兩個參數控制表達式最大長度
- unsigned char left;
- unsigned char right;///括號起始和結束
- int opverify( char*s)///檢查運算符是否有錯誤的函數
- {
- unsigned char i,flagl=0,flagr=0;
- int a;
- for(i=0;i<LEN;i++)
- {
- if(s[i]==43||s[i]==45)
- {
- flagr=0;
- for(a=i+1;a<LEN;a++) ///右邊有數字
- {
- if(s[a]==46||(s[a]>=48&&s[a]<=57)||s[a]==40)
- {
- flagr=1;
- break;
- }
- if(s[a]==42||s[a]==47||s[a]==41)
- {
- return i;
- }
- }
- if(flagr==0)
- return i;
- }
- if(s[i]==42||s[i]==47)
- {
- flagl=0;flagr=0;
- for(a=i-1;i>=0;a--) ///左邊有數字
- {
- if(s[a]==46||(s[a]>=48&&s[a]<=57)||s[a]==41)
- {
- flagl=1;
- break;
- }
- if(s[a]==42||s[a]==47||s[a]==40)
- {
- return i;
- }
- }
- for(a=i+1;a<LEN;a++) ///右邊有數字
- {
- if(s[a]==46||(s[a]>=48&&s[a]<=57)||s[a]==40)
- {
- flagr=1;
- break;
- }
- if(s[a]==42||s[a]==47||s[a]==41)
- {
- return i;
- }
- }
- if(flagl==0||flagr==0)
- return i;
- }
- }
- return -1;
- }
- int dotverify( char*s)///檢查小數點是否有錯誤的函數
- {
- unsigned char i,dotcount,numcount;
- for(i=0;i<LEN;i++)
- {
- if(s[i]==46||(s[i]>=48&&s[i]<=57))
- {
- dotcount=0;
- numcount=0;
- while(1)
- {
- if(s[i]==46)
- {
- dotcount++;
- i++;
- continue;
- }
- if(s[i]>=48&&s[i]<=57)
- {
- numcount++;
- i++;
- continue;
- }
- break;
- }
- if(dotcount>1||numcount==0)
- {
- while(s[i]!=46)
- i--;
- return i;
- }
- }
- }
- return -1;
- }
- int kuohaoverify( char*s)///檢查括號是否有錯誤的函數
- {
- unsigned char i;
- char wrongposition=0;
- int flag=0;
- for(i=0;i<LEN;i++)
- {
- if(i>0)
- if(s[i-1]==40&&s[i]==41)
- return wrongposition;
- if(s[i]==40)
- flag++;
- if(s[i]==41)
- flag--;
- if(flag<0)
- return wrongposition;
- if(s[i]!=0)
- wrongposition++;
- }
- if(flag==0)
- return -1;
- return wrongposition;
- }
- int kuohaolocater( char*s)///定位內層配對括號起點和終點
- {
- unsigned char i;
- for(i=0;i<LEN;i++)
- {
- if(s[i]==40)
- left=i;
- if(s[i]==41)
- {
- right=i;
- return 1;
- }
-
- }
- return 0;
- }
- void convert( char*s,float*num)///原始字符串分離成運算符和編號數組+浮點數組
- {
- int source=LEN-1,target=LEN-2;
- unsigned char count=0;
- while(s[source]==0)
- source--;
- count=target-source;
- while(source>=0)
- {
- s[target]=s[source];
- target--;
- source--;
- }
- for(source=0;source<count;source++)
- s[source]=0;
- source=count;target=0;count=0;
- while(source<LEN)
- {
- if(s[source]==46||(s[source]>=48&&s[source]<=57))
- {
- num[count]=(float)atof(s+source);
- s[target]=48+count;
- count++;
- source++;
- target++;
- while(s[source]==46||(s[source]>=48&&s[source]<=57))
- source++;
- continue;
- }
- if(s[source]==41&&(s[source+1]==46||(s[source+1]>=48&&s[source+1]<=57)))
- {
- s[target]=s[source];
- target++;
- source++;
- s[target]=42;
- target++;
- continue;
- }
- if(s[source]==40&&(s[source-1]==46||(s[source-1]>=48&&s[source-1]<=57)))
- {
- s[target]=42;
- target++;
- }
- s[target]=s[source];
- target++;
- source++;
- }
- for(source=target;source<LEN;source++)
- s[source]=0;
- }
- void signprocess(char *s,float*num)///運算符處理函數,負責處理符號以及處理一些不標準的寫法
- {
- unsigned char flagl;
- int a,i;
- for(i=right;i>=left;i--)
- {
- if(s[i]==43||s[i]==45)
- {
- flagl=0;
- for(a=i-1;a>=left;a--) ///zuobianyoushuzi
- {
- if(s[a]>=48)
- {
- flagl=1;
- break;
- }
- if(s[a]>=40&&s[a]<=47)
- {
- break;
- }
- }
- if(flagl==0)
- {
- if(s[i]==43)
- s[i]=0;
- if(s[i]==45)
- {
- s[i]=0;
- for(a=i+1;;a++)
- if(s[a]>=48)
- {
- num[s[a]-48]=-num[s[a]-48];
- break;
- }
- }
- }
- }
- }
- }
- void multipledivide(char *s,float*num)///乘除法計算函數
- {
- unsigned char i,flagl,flagr,a;
- for(i=left+1;i<right;i++)
- {
- if(s[i]==42||s[i]==47)
- {
- for(a=i+1;;a++)
- if(s[a]>=48)
- {
- flagr=s[a]-48;
- break;
- }
- for(a=i-1;;a--)
- if(s[a]>=48)
- {
- flagl=s[a]-48;
- break;
- }
- if(s[i]==42)
- {
- num[flagr]=num[flagl]*num[flagr];
- s[a]=0;
- s[i]=0;
- }
- if(s[i]==47)
- {
- num[flagr]=num[flagl]/num[flagr];
- s[a]=0;
- s[i]=0;
- }
- }
- }
- }
- void addminus(char*s,float*num)///加減法計算函數
- {
- unsigned char i,flagl,flagr,a;
- for(i=left+1;i<right;i++)
- {
- if(s[i]==43||s[i]==45)
- {
- for(a=i+1;;a++)
- if(s[a]>=48)
- {
- flagr=s[a]-48;
- break;
- }
- for(a=i-1;;a--)
- if(s[a]>=48)
- {
- flagl=s[a]-48;
- break;
- }
- if(s[i]==43)
- {
- num[flagr]=num[flagl]+num[flagr];
- s[a]=0;
- s[i]=0;
- }
- if(s[i]==45)
- {
- num[flagr]=num[flagl]-num[flagr];
- s[a]=0;
- s[i]=0;
- }
- }
- }
- }
- void singlecacu(char*s,float*num)///中間層運算函數,不帶括號的計算函數,可以處理無括號的表達式
- {
- signprocess(s,num);
- printf("***正負號處理完畢***\n");
- multipledivide(s,num);
- printf("***乘除完畢***\n");
- addminus(s,num);
- printf("***加減完畢***\n");
- if(s[left]==40)
- {
- printf("***去括號***\n");
- s[left]=0;
- }
- if(s[right]==41)
- s[right]=0;///每次計算都將被處理的運算數、運算符、括號抹掉并在原位值寫入本次計算結果,這樣表達式越來越簡。
- }
- void caculate (char*s,float*num)///頂層運算函數,循環調用括號查找和無括號計算函數,直到把括號消完
- {
- while(kuohaolocater(s))
- singlecacu(s,num);
- left=0;right=LEN-1;
- singlecacu(s,num);
- }
- void display(char*s,float*num)///顯示最終結果
- {
- unsigned char i;
- for(i=0;i<LEN;i++)
- if(s[i]>=48)
- {
- printf("結果:%f",num[s[i]-48]);
- break;
- }
- }
- int main()///注意不要使用中文括號和小數點
- {
- char wrongposition;///表達式錯誤位置
- unsigned char i;
- char s[LEN];///STEP1:初始化部分開始
- for(i=0;i<LEN;i++)
- {
- s[i]=0;
- }
- float num[FLOAT];
- for(i=0;i<FLOAT;i++)
- {
- num[i]=0;
- }///初始化部分結束
- printf("輸入表達式\n");
- scanf("%s",s);
- ///STEP2:表達式查錯開始
- wrongposition=kuohaoverify(s);
- if(kuohaoverify(s)!=-1)
- {
- printf("括號錯誤\n位置:%d\n",wrongposition);
- return 0;
- }
- printf("括號檢查完畢\n");
- wrongposition=dotverify(s);
- if(dotverify(s)!=-1)
- {
- printf("小數點錯誤\n位置:%d\n",wrongposition);
- return 0;
- }
- printf("小數點檢查完畢\n");
- wrongposition=opverify(s);
- if(opverify(s)!=-1)
- {
- printf("運算符錯誤\n位置:%d\n",wrongposition);
- return 0;
- }
- printf("運算符檢查完畢\n");
- ///表達式查錯部分結束
- ///STEP3:開始處理表達式,數據與運算符分離
- convert(s,num);
- printf("%s\n",s);
- for(i=0;i<FLOAT;i++)
- printf("%f ",num[i]);
- printf("\n***數據與運算符分離完畢***\n");
- printf("\n");
- ///表達式處理完成
- ///STEP4:開始計算
- caculate(s,num);
- display(s,num);
- return 0;
- }
復制代碼
所有資料51hei提供下載:
計算器代碼.rar
(2.13 KB, 下載次數: 8)
2018-5-5 17:21 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|