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