基于C語(yǔ)言編寫一個(gè)多功能計(jì)算器
用C語(yǔ)言寫一個(gè)計(jì)算器,除了四則混合運(yùn)算之外,還支持三角函數(shù)和絕對(duì)值等函數(shù)。
PS E:\Code\PL\calc> .\a.exe abs(3*5-4^2) abs(3*5-4^2)=1.000000 25-7+6*(4-5) 25-7+6*(4-5)=12.000000
在計(jì)算器中,至少包含兩類變量,即數(shù)字和運(yùn)算符。例如,如果希望實(shí)現(xiàn)a+b×(c−d)這樣一個(gè)簡(jiǎn)單的功能,要求編譯器可以識(shí)別出+,×,−,(,)這五個(gè)符號(hào),并理清彼此的計(jì)算順序,最后生成一棵語(yǔ)法樹,然后實(shí)現(xiàn)輸出。
1. 加減法運(yùn)算
萬(wàn)事開頭難,所以我們選擇一個(gè)簡(jiǎn)單到無(wú)腦的開頭。首先,我們考慮實(shí)現(xiàn)a + b a+ba+b這樣簡(jiǎn)單的兩數(shù)運(yùn)算,即如下所示,十分簡(jiǎn)單且無(wú)腦。
void douCalc(){
while (1){
double i, j, s;
char k;
scanf("%lf%c%lf", &i, &k, &j);
switch (k){
case '+':
s = i+j;
break;
case '-':
s = i-j;
break;
case '*':
s = i*j;
break;
case '/':
s = i/j;
break;
default:
break;
}
printf("%lf\n", s);
}
}然后,我們考慮,如何實(shí)現(xiàn)一個(gè)連加器,旨在解決a+b+c+...的計(jì)算問(wèn)題。這里雖然不涉及到運(yùn)算次序,但仍舊需要處理多個(gè)不確定個(gè)數(shù)的變量,所以我們不再可以直接用類似scanf("%lf%c%lf", &i, &k, &j);的方案來(lái)實(shí)現(xiàn)數(shù)據(jù)的輸入,而必須建立一個(gè)鏈表來(lái)存儲(chǔ)變量。
C語(yǔ)言輸入輸出
在C語(yǔ)言中,可以通過(guò)至少三種方式來(lái)讀取鍵盤輸入的值:
- scanf():和 printf() 類似,scanf() 可以輸入多種類型的數(shù)據(jù)。
- getchar()、getche()、getch():這三個(gè)函數(shù)都用于輸入單個(gè)字符。
- gets():獲取一行數(shù)據(jù),并作為字符串處理。
其中,scanf是格式化掃描的意思,可以通過(guò)格式控制符對(duì)輸入字符進(jìn)行格式化,并賦值給相關(guān)變量。
| 格式控制符 | 說(shuō)明 |
|---|---|
| %c | 讀取單一字符 |
| %s | 讀取一個(gè)字符串(以空白符為結(jié)束) |
| %f、%lf | 讀取十進(jìn)制形式小數(shù),賦值給float、double 類型 |
| %e、%le | 讀取指數(shù)形式小數(shù),賦值給 float、double 類型 |
| %g、%lg | 讀取十進(jìn)制或指數(shù)形式的小數(shù), 并分別賦值給 float、double 類型 |
整數(shù)格式化
| short | int | long | |
|---|---|---|---|
| 十進(jìn)制 | %hd | %d | %ld |
| 八進(jìn)制 | %ho | %o | %lo |
| 十六進(jìn)制 | %hx | %x | %lx |
| 無(wú)符號(hào) | %hu | %u | %lu |
getchar()等價(jià)于scanf("%c", c),相對(duì)來(lái)說(shuō)更加簡(jiǎn)單。getche和getch是Windows獨(dú)有的函數(shù),在頭文件conio.h中故不贅述。
gets和scanf(%s,s)的區(qū)別在于,后者在使用的過(guò)程中會(huì)把空格當(dāng)作終止符,而前者不會(huì)。
所以,我們?cè)趯?shí)現(xiàn)連加的過(guò)程中,會(huì)使用gets作為交互方法。
由于我們實(shí)現(xiàn)的是一個(gè)連加器,所以輸入字符中只包含數(shù)字和加號(hào),那么接下來(lái),我們需要遍歷輸入字符,通過(guò)加號(hào)來(lái)將數(shù)字分開。我們可以很方便地寫下一個(gè)簡(jiǎn)單而丑陋的小程序。
void adds(){
char str[100];
char numStr[20];
int num[20];
int val;
int i,j,k;
while (1){
gets(str);
i = 0;j = 0;k = 0;
while (str[i]!='\0'){
if (str[i]=='+'){
num[k] = atoi(numStr);
k++;
j = 0;
}else{
numStr[j] = str[i];
j++;
}
i++;
}
num[k]=atoi(numStr);
val = 0;
for (int i = 0; i < k+1; i++){
val += num[i];
}
printf("%d\n",val);
}
}
int main(){
adds();
return 0;
}由于加減法具有相同的運(yùn)算優(yōu)先級(jí),在實(shí)現(xiàn)上不過(guò)是為后續(xù)的數(shù)字加上一個(gè)負(fù)號(hào)而已,故可十分方便地在原有程序上修改。
此外,adds代碼乍看上去沒(méi)什么問(wèn)題,但str的值在更新之前,并不會(huì)自動(dòng)清零,由此帶來(lái)的bug需要?jiǎng)?chuàng)建一個(gè)字符串清零的函數(shù)。修改之后的代碼如下
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
void strClear(char *str,int n){
for (int i = 0; i < n; i++){
str[i]=NULL;
}
}
void adds(){
char str[100];
char numStr[20];
int num[20];
int val;
int i,j,k;
while (1){
gets(str);
i = 0;j = 0;k = 0;
while (str[i]!='\0'){
if (str[i]=='+'){
num[k] = atoi(numStr);
strClear(numStr,20);
k++;
j = 0;
}else if (str[i]=='-'){
num[k] = atoi(numStr);
strClear(numStr,20);
k++;
numStr[0] = str[i];
j = 1;
}else{
numStr[j] = str[i];
j++;
}
i++;
}
num[k]=atoi(numStr);
strClear(numStr,20);
val = 0;
for (int i = 0; i < k+1; i++){
val += num[i];
}
printf("%d\n",val);
}
}
int main(){
adds();
return 0;
}精簡(jiǎn)一下
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
void strClear(char *str,int n){
for (int i = 0; i < n; i++){
str[i]='\0';
}
}
void adds1(){
char str[100];
char numStr[20];
int i,j,val;
while (1){
gets(str);
i = 0;j = 0;val = 0;
while (str[i]!='\0'){
if ((str[i]=='+')||(str[i]=='-')){
val += atoi(numStr);
strClear(numStr,20);
j = 0;
if (str[i]=='-')
numStr[j++]=str[i];
}else
numStr[j++] = str[i];
i++;
}
val += atoi(numStr);
strClear(numStr,20);
printf("%d\n",val);
}
}
int main(){
adds1();
return 0;
}2. 加法和乘法
若希望加入乘法和除法,那么修改代碼的過(guò)程就相對(duì)復(fù)雜了,因?yàn)槌顺ㄔ谶\(yùn)算過(guò)程中,具有比加減法更高的優(yōu)先級(jí)。那么我們就無(wú)法通過(guò)一個(gè)簡(jiǎn)單的數(shù)組來(lái)存儲(chǔ)變量,而必須建立一種樹形的結(jié)構(gòu)。
例如,對(duì)于a+b×c−d×e/f,可寫成如下形式

我們可以看到,這是一個(gè)二叉樹,每個(gè)葉節(jié)點(diǎn)都是數(shù)字,而兩個(gè)葉節(jié)點(diǎn)的父節(jié)點(diǎn)則為運(yùn)算符。我們通過(guò)這個(gè)運(yùn)算符來(lái)計(jì)算其子節(jié)點(diǎn)后,刪除它的兩個(gè)子節(jié)點(diǎn),同時(shí)運(yùn)算符所對(duì)應(yīng)的節(jié)點(diǎn)退化為葉節(jié)點(diǎn),同時(shí)其類型也變?yōu)閿?shù)字。
對(duì)于上圖而言,先計(jì)算e/f,然后計(jì)算b×c和d×e/f,再計(jì)算b×c−d×e/f,最后計(jì)算最上面的加法。
對(duì)于樹來(lái)說(shuō),我們的遍歷往往從根節(jié)點(diǎn)開始,所以其計(jì)算規(guī)則如下:
- 如果當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)為葉節(jié)點(diǎn),則計(jì)算當(dāng)前節(jié)點(diǎn),并刪除該節(jié)點(diǎn)的葉節(jié)點(diǎn),然后考慮其父節(jié)點(diǎn)。
- 如果當(dāng)前節(jié)點(diǎn)的某個(gè)子節(jié)點(diǎn)不是葉節(jié)點(diǎn),則處理該子節(jié)點(diǎn),直到該子節(jié)點(diǎn)成為葉節(jié)點(diǎn)為止。
- 如果當(dāng)前節(jié)點(diǎn)為根節(jié)點(diǎn),且為葉節(jié)點(diǎn),則輸出計(jì)算結(jié)果。
對(duì)于節(jié)點(diǎn)來(lái)說(shuō),除了父子節(jié)點(diǎn)外,則至少有兩個(gè)屬性:
- isLeaf:用于葉節(jié)點(diǎn)判定。在這里,葉節(jié)點(diǎn)不僅有結(jié)構(gòu)上的意義,更有著明確的語(yǔ)義:它只能是數(shù)字。
- value:對(duì)于葉節(jié)點(diǎn)而言,這個(gè)值為數(shù)字,否則的話,這個(gè)值為運(yùn)算符號(hào)及其所對(duì)應(yīng)的計(jì)算規(guī)則。
# define MAXLEN 100
typedef struct NODE{
struct NODE *father;
struct NODE *Left;
struct NODE *Right;
char value[MAXLEN];
int isLeaf;
}Node;生成計(jì)算樹
由于我們規(guī)定了兩個(gè)運(yùn)算層級(jí),所以再遍歷字符串以生成計(jì)算樹的過(guò)程中,需要兩次循環(huán),即首先生成加減法的計(jì)算樹,然后再生成乘除法的計(jì)算樹。
生成計(jì)算樹的過(guò)程可以簡(jiǎn)化為字符串不斷拆分的過(guò)程,為了簡(jiǎn)化思維,我們只考慮兩個(gè)符號(hào)+和*,這兩個(gè)符號(hào)分別代表兩種計(jì)算層級(jí)。
由此可得到如下代碼。對(duì)于
# define TRUE 1
# define FALSE 0
void newNode(Node *root, Node *father){
root -> father = father;
root ->Left = NULL;
root -> Right = NULL;
root -> isLeaf = FALSE;
}
//root 為根節(jié)點(diǎn),str為字符串
void initCalcTree(Node *root, char flag){
for (int i = 0; i < MAXLEN; i++){
if (root->value[i]==flag){
Node *Left = (Node *)malloc(sizeof(Node));
Node *Right = (Node *)malloc(sizeof(Node));
newNode(Left,root);
newNode(Right,root);
for (int j = 0; j < i; j++)
Left -> value[j] = root->value[j];
Left->value[i] = '\0';
i++;
for (int j = i; j < MAXLEN; j++)
Right -> value[j-i] = root->value[j];
root->Left = Left;
root->Right = Right;
strClear(root->value,MAXLEN);
root->value[0] = flag;
root->value[1] = '\n';
initCalcTree(Left,'*');
if (flag=='+')
initCalcTree(Right,'+');
else
initCalcTree(Right,'*');
break;
}else{
if (root->value[i]=='\0'){
if(flag =='+')
initCalcTree(root,'*');
else
root -> isLeaf = TRUE;
break;
}
else
continue;
}
}
}測(cè)試一下
void printNode(Node *root,int start){
printf("the %dth node is %s\n", start, root->value);
if (root->isLeaf==FALSE){
printNode(root->Left, start + 1);
printNode(root->Right, start + 1);
}
}
int main(){
Node *root = (Node *)malloc(sizeof(Node));
char *str = "1+21*3+3*4*5+6";
strcpy(root->value,str);
initCalcTree(root,'+');
printNode(root,0);
return 0;
}得到結(jié)果為
the 0th node is +
the 1th node is 1
the 1th node is +
the 2th node is *
the 3th node is 21
the 3th node is 3
the 2th node is +
the 3th node is *
the 4th node is 3
the 4th node is *
the 5th node is 4
the 5th node is 5
the 3th node is 6
然后,我們?cè)賹?duì)計(jì)算樹進(jìn)行計(jì)算。當(dāng)被計(jì)算的量為葉節(jié)點(diǎn)時(shí),則返回該節(jié)點(diǎn)的值;如果該節(jié)點(diǎn)的兩個(gè)節(jié)點(diǎn)都是葉節(jié)點(diǎn),則返回該節(jié)點(diǎn)處的運(yùn)算符對(duì)這兩個(gè)子節(jié)點(diǎn)的計(jì)算值;如果該節(jié)點(diǎn)的兩個(gè)節(jié)點(diǎn)都不是葉節(jié)點(diǎn),那么對(duì)這兩個(gè)子節(jié)點(diǎn)進(jìn)行計(jì)算。
int calcNode(Node *root){
if(root->isLeaf == TRUE)
return atoi(root->value);
else if (root->Left->isLeaf * root->Right->isLeaf == TRUE){
if(root->value[0] == '+')
return atoi(root->Left->value)+atoi(root->Right->value);
else
atoi(root->Left->value)*atoi(root->Right->value);
}else{
if (root->value[0] == '+')
return calcNode(root->Left)+calcNode(root->Right);
else
return calcNode(root->Left)*calcNode(root->Right);
}
}
int main(){
Node *root = (Node *)malloc(sizeof(Node));
char str[MAXLEN];
while (1){
gets(str);
strcpy(root->value,str);
initCalcTree(root,'+');
printf("%s=%d\n",str,calcNode(root));
}
return 0;
}結(jié)果為
PS E:\Code\PL\calc> .\a.exe
1+2+3*4+15*2
1+2+3*4+15*2=45
2*5+3*6*12
2*5+3*6*12=226
3. 四則混合運(yùn)算
如果考慮加減乘除,那么意味著一個(gè)運(yùn)算級(jí)別下有多種運(yùn)算符,所以我們需要通過(guò)一個(gè)函數(shù)來(lái)返回運(yùn)算符的運(yùn)算次序。
int getOrder(char ch){
int result;
switch (ch){
case '+':
case '-':
return 0;
case '*':
case '/':
return 1;
default:
return 2;
}
}然后,基于此,修改計(jì)算樹的生成與計(jì)算代碼。
int douCalc(char c,int a, int b){
switch (c){
case '+':
return a+b;
case '-':
return a-b;
case '*':
return a*b;
case '/':
return a/b;
}
}
void newNode(Node *root, Node *father){
root -> father = father;
root ->Left = NULL;
root -> Right = NULL;
root -> isLeaf = TRUE;
father -> isLeaf = FALSE;
}
//root 為根節(jié)點(diǎn),str為字符串,N為字符串長(zhǎng)度
void initCalcTree(Node *root, int order){
for (int i = 0; i < MAXLEN; i++){
if (getOrder(root->value[i])==order){
Node *Left = (Node *)malloc(sizeof(Node));
Node *Right = (Node *)malloc(sizeof(Node));
newNode(Left,root);
newNode(Right,root);
for (int j = 0; j < i; j++)
Left -> value[j] = root->value[j];
Left->value[i] = '\0';
i++;
for (int j = i; j < MAXLEN; j++)
Right -> value[j-i] = root->value[j];
root->Left = Left;
root->Right = Right;
root->value[0] = root->value[i-1];
root->value[1] = '\0';
initCalcTree(Right,order);
if (order<1)
initCalcTree(Left,order+1);
break;
}
else if((i==0)&&(order<2))
initCalcTree(root,order+1);
}
}
int calcNode(Node *root){
if(root->isLeaf == TRUE)
return atoi(root->value);
else if (root->Left->isLeaf * root->Right->isLeaf == TRUE)
return douCalc(root->value[0],
atoi(root->Left->value),atoi(root->Right->value));
else
return douCalc(root->value[0],
calcNode(root->Left),calcNode(root->Right));
}
int main(){
Node *root = (Node *)malloc(sizeof(Node));
char str[MAXLEN];
while (1){
gets(str);
strcpy(root->value,str);
initCalcTree(root,0);
printf("%s=%d\n",str,calcNode(root));
}
return 0;
}至此,我們得到了一個(gè)計(jì)算器的“骨架”,為運(yùn)算符設(shè)定相應(yīng)的運(yùn)算次序,相當(dāng)于提供一種生成方法,這種方法可以直接擴(kuò)展到更多的運(yùn)算符上。
同時(shí),上述代碼中也出現(xiàn)了兩個(gè)問(wèn)題:
我們默認(rèn)計(jì)算的是整型數(shù)據(jù),所以無(wú)法處理浮點(diǎn)型運(yùn)算
減法和除法雖然在名義上與加法、乘法處于相同的運(yùn)算次序中,但我們的生成樹中默認(rèn)的是從右向左計(jì)算。對(duì)于a+b−c+d這樣的表達(dá)式,會(huì)計(jì)算成a+b−(c+d)的形式,這是錯(cuò)誤的。
針對(duì)這種運(yùn)算結(jié)構(gòu)的一個(gè)優(yōu)勢(shì)和兩個(gè)問(wèn)題,我們繼續(xù)改進(jìn)這個(gè)計(jì)算器程序。
4. 浮點(diǎn)型計(jì)算器程序
首先,我們將所有函數(shù)與變量均改為double類型;然后我們更改輸入字符串的遍歷方式,從后向前進(jìn)行遍歷。
我們?cè)偌尤氤朔竭\(yùn)算符^,給它一個(gè)更高的運(yùn)算層級(jí)
int getOrder(char ch){
int result;
switch (ch){
case '+':
case '-':
return 0;
case '*':
case '/':
return 1;
case '^':
return 2;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return 3;
default:
return 4;
}
}
double douCalc(char c,double a, double b){
switch (c){
case '+': return a+b;
case '-': return a-b;
case '*': return a*b;
case '/': return a/b;
case '^': return pow(a,b);
}
}至此,我們寫出了一個(gè)可以計(jì)算+-x÷^的程序。但我們還不能處理表達(dá)式中可能出現(xiàn)的括號(hào)。
括號(hào)在表達(dá)式中成對(duì)出現(xiàn),故不同于常規(guī)運(yùn)算符,需要在表達(dá)式的兩端進(jìn)行遍歷;另外,括號(hào)不具備運(yùn)算功能,只有規(guī)定運(yùn)算次序的作用,對(duì)于括號(hào)運(yùn)算符只有一個(gè)子節(jié)點(diǎn)。所以,只需更改initCalcTree的代碼。
由于我們將算法改為從右向左遍歷,所以如果最后一個(gè)字符不是),則不必考慮括號(hào)的影響。當(dāng)最后一個(gè)字符為)時(shí),如果第0個(gè)字符為(,則將括號(hào)里面的內(nèi)容提取出來(lái),針對(duì)此時(shí)的節(jié)點(diǎn)重新進(jìn)行遍歷即可。如果自左向右遍歷的過(guò)程出現(xiàn)第一個(gè)(的位置是posLeft,則后面關(guān)于運(yùn)算符的遍歷從posLeft開始。
//root 為根節(jié)點(diǎn),str為字符串,N為字符串長(zhǎng)度
void initCalcTree(Node *root, int order){
int lenStr = strlen(root->value);
int posLeft = lenStr;
//如果末尾為')',則查找其對(duì)應(yīng)的左括號(hào)的位置
if(root->value[lenStr-1]==')'){
for (int i = 0; i < lenStr; i++)
if(root->value[i]=='(')
posLeft = i;
if (posLeft == 0){
for (int i = 1; i < lenStr-1; i++)
root->value[i-1] = root->value[i];
root->value[lenStr-2]='\0';
initCalcTree(root,0);
}
}
//如果左括號(hào)的位置不為0,則
for (int i = posLeft; i >= 0; i--){
if (getOrder(root->value[i])==order){
Node *Left = (Node *)malloc(sizeof(Node));
Node *Right = (Node *)malloc(sizeof(Node));
newNode(Left,root);
newNode(Right,root);
for (int j = 0; j < i; j++)
Left -> value[j] = root->value[j];
Left->value[i] = '\0';
i++;
for (int j = i; j < MAXLEN; j++)
Right -> value[j-i] = root->value[j];
root->Left = Left;
root->Right = Right;
root->value[0] = root->value[i-1];
root->value[1] = '\0'; //字符串末尾標(biāo)記
initCalcTree(Left,order);
if ((order<2)||(posLeft!=lenStr))
initCalcTree(Right,order+1);
break;
}
else if((i==0)&&(order<2))
initCalcTree(root,order+1);
}
}至此,我們就寫好了一個(gè)簡(jiǎn)陋的可以進(jìn)行四則混合運(yùn)算的計(jì)算器程序
PS E:\Code\PL\calc> .\a.exe
1+2*(3-4)+5
1+2*(3-4)+5=4.000000
2^(3+1)
2^(3+1)=16.000000
5. 加入三角函數(shù)
現(xiàn)在我們需要考慮加入三角函數(shù),其難點(diǎn)在于函數(shù)的識(shí)別。
我們規(guī)定,單變量函數(shù)通過(guò)括號(hào)的方式導(dǎo)入實(shí)參,也就是說(shuō),只要表達(dá)式中不出現(xiàn)括號(hào),那么就不必考慮括號(hào)的問(wèn)題。換句話說(shuō),判定函數(shù),必然在判定括號(hào)之后。
考慮到我們定義的getOrder函數(shù)中,除了我們所規(guī)定的符號(hào)和數(shù)字之外,其他符號(hào)和字母的默認(rèn)返回值為4。所以需要在判定括號(hào)之后,繼續(xù)進(jìn)行函數(shù)的判斷。
故而需要更改括號(hào)判定的代碼
/*...*/
if(root->value[lenStr-1]==')'){
for (int i = 0; i < lenStr; i++)
if(root->value[i]=='(')
posLeft = i;
if (posLeft == 0){
for (int i = 1; i < lenStr-1; i++)
root->value[i-1] = root->value[i];
root->value[lenStr-2]='\0';
initCalcTree(root,0);
}else{
int lenFunc=0;
posLeft--;
while ((getOrder(root->value[posLeft])==4)&&(posLeft>0)){
posLeft--;
lenFunc++;}
//當(dāng)posLeft變?yōu)?時(shí),說(shuō)明此節(jié)點(diǎn)為無(wú)法分割的函數(shù)
if (posLeft==0){
root->value[lenFunc+1]='\0';
Node *Left = (Node *)malloc(sizeof(Node));
root->Left = Left;
newNode(Left,root);
for (int i = lenFunc+2; i < lenStr-1; i++){
Left->value[i-lenFunc-2]=root->value[i];
}
Left->value[lenStr-lenFunc-2]='\0';
initCalcTree(Left,0); //對(duì)左子節(jié)點(diǎn)進(jìn)行生成
return 0;
}
}
}
/*...*/接下來(lái),我們需要修改calcNode函數(shù),即在計(jì)算運(yùn)算符之前,添加一個(gè)函數(shù)處理程序。其中,strcmp為字符串比對(duì)函數(shù),當(dāng)兩個(gè)字符串相等時(shí),返回0。
double doFunc(char *str,double val){
if (strcmp(str,"sin")==0)
return sin(val);
else if (strcmp(str,"cos")==0)
return cos(val);
else if (strcmp(str,"tan")==0)
return tan(val);
else if (strcmp(str,"arcsin")==0)
return asin(val);
else if (strcmp(str,"arccos")==0)
return acos(val);
else if (strcmp(str,"arctan")==0)
return atan(val);
else if (strcmp(str,"sqrt")==0)
return sqrt(val);
else if (strcmp(str,"abs")==0)
return abs(val);
}
double calcNode(Node *root){
if(getOrder(root->value[0])==4)
return doFunc(root->value,calcNode(root->Left));
if(root->isLeaf == TRUE)
return atof(root->value);
else if (root->Left->isLeaf * root->Right->isLeaf == TRUE)
return douCalc(root->value[0],
atof(root->Left->value),atof(root->Right->value));
else
return douCalc(root->value[0],
calcNode(root->Left),calcNode(root->Right));
}至此,我們已經(jīng)用C語(yǔ)言實(shí)現(xiàn)了一個(gè)簡(jiǎn)陋而且有不少bug的計(jì)算器,比如并未設(shè)置除零報(bào)警之類的功能,但一般的操作是沒(méi)有問(wèn)題的。
abs(3*5-4^2)
abs(3*5-4^2)=1.000000
25-7+6*(4-5)
25-7+6*(4-5)=12.000000
以上就是基于C語(yǔ)言編寫一個(gè)多功能計(jì)算器的詳細(xì)內(nèi)容,更多關(guān)于C語(yǔ)言計(jì)算器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于C語(yǔ)言位運(yùn)算的簡(jiǎn)單示例
這篇文章主要介紹了關(guān)于C語(yǔ)言位運(yùn)算的簡(jiǎn)單示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
C++實(shí)現(xiàn)LeetCode(58.求末尾單詞的長(zhǎng)度)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(58.求末尾單詞的長(zhǎng)度),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C++實(shí)現(xiàn)線性表順序存儲(chǔ)的示例代碼
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)線性表順序存儲(chǔ)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下2023-03-03
C語(yǔ)言編程簡(jiǎn)單卻重要的數(shù)據(jù)結(jié)構(gòu)順序表全面講解
這篇文章主要為大家介紹了C語(yǔ)言編程中非常簡(jiǎn)單卻又非常重要的數(shù)據(jù)結(jié)構(gòu)順序表的全面講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10

