欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于C語言編寫一個(gè)多功能計(jì)算器

 更新時(shí)間:2023年08月11日 10:07:33   作者:微小冷  
這篇文章主要為大家詳細(xì)介紹了如何基于C語言編寫一個(gè)多功能計(jì)算器,除了四則混合運(yùn)算之外,還支持三角函數(shù)和絕對(duì)值等函數(shù),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

用C語言寫一個(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ì)算順序,最后生成一棵語法樹,然后實(shí)現(xiàn)輸出。

1. 加減法運(yùn)算

萬事開頭難,所以我們選擇一個(gè)簡(jiǎn)單到無腦的開頭。首先,我們考慮實(shí)現(xiàn)a + b a+ba+b這樣簡(jiǎn)單的兩數(shù)運(yùn)算,即如下所示,十分簡(jiǎn)單且無腦。

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ì)算問題。這里雖然不涉及到運(yùn)算次序,但仍舊需要處理多個(gè)不確定個(gè)數(shù)的變量,所以我們不再可以直接用類似scanf("%lf%c%lf", &i, &k, &j);的方案來實(shí)現(xiàn)數(shù)據(jù)的輸入,而必須建立一個(gè)鏈表來存儲(chǔ)變量。

C語言輸入輸出

在C語言中,可以通過至少三種方式來讀取鍵盤輸入的值:

  • scanf():和 printf() 類似,scanf() 可以輸入多種類型的數(shù)據(jù)。
  • getchar()、getche()、getch():這三個(gè)函數(shù)都用于輸入單個(gè)字符。
  • gets():獲取一行數(shù)據(jù),并作為字符串處理。

其中,scanf是格式化掃描的意思,可以通過格式控制符對(duì)輸入字符進(jìn)行格式化,并賦值給相關(guān)變量。

格式控制符說明
%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ù)格式化

shortintlong
十進(jìn)制%hd%d%ld
八進(jìn)制%ho%o%lo
十六進(jìn)制%hx%x%lx
無符號(hào)%hu%u%lu

getchar()等價(jià)于scanf("%c", c),相對(duì)來說更加簡(jiǎn)單。getche和getch是Windows獨(dú)有的函數(shù),在頭文件conio.h中故不贅述。

gets和scanf(%s,s)的區(qū)別在于,后者在使用的過程中會(huì)把空格當(dāng)作終止符,而前者不會(huì)。

所以,我們?cè)趯?shí)現(xiàn)連加的過程中,會(huì)使用gets作為交互方法。

由于我們實(shí)現(xiàn)的是一個(gè)連加器,所以輸入字符中只包含數(shù)字和加號(hào),那么接下來,我們需要遍歷輸入字符,通過加號(hào)來將數(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)上不過是為后續(xù)的數(shù)字加上一個(gè)負(fù)號(hào)而已,故可十分方便地在原有程序上修改。

此外,adds代碼乍看上去沒什么問題,但str的值在更新之前,并不會(huì)自動(dòng)清零,由此帶來的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. 加法和乘法

若希望加入乘法和除法,那么修改代碼的過程就相對(duì)復(fù)雜了,因?yàn)槌顺ㄔ谶\(yùn)算過程中,具有比加減法更高的優(yōu)先級(jí)。那么我們就無法通過一個(gè)簡(jiǎn)單的數(shù)組來存儲(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)算符。我們通過這個(gè)運(yùn)算符來計(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ì)于樹來說,我們的遍歷往往從根節(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)來說,除了父子節(jié)點(diǎn)外,則至少有兩個(gè)屬性:

  • isLeaf:用于葉節(jié)點(diǎn)判定。在這里,葉節(jié)點(diǎn)不僅有結(jié)構(gòu)上的意義,更有著明確的語義:它只能是數(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ì)算樹的過程中,需要兩次循環(huán),即首先生成加減法的計(jì)算樹,然后再生成乘除法的計(jì)算樹。

生成計(jì)算樹的過程可以簡(jiǎn)化為字符串不斷拆分的過程,為了簡(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)算符,所以我們需要通過一個(gè)函數(shù)來返回運(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è)問題:

我們默認(rèn)計(jì)算的是整型數(shù)據(jù),所以無法處理浮點(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è)問題,我們繼續(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)容提取出來,針對(duì)此時(shí)的節(jié)點(diǎn)重新進(jìn)行遍歷即可。如果自左向右遍歷的過程出現(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ù)通過括號(hào)的方式導(dǎo)入實(shí)參,也就是說,只要表達(dá)式中不出現(xiàn)括號(hào),那么就不必考慮括號(hào)的問題。換句話說,判定函數(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í),說明此節(jié)點(diǎn)為無法分割的函數(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;
            }
        }
    }
/*...*/

接下來,我們需要修改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語言實(shí)現(xiàn)了一個(gè)簡(jiǎn)陋而且有不少bug的計(jì)算器,比如并未設(shè)置除零報(bào)警之類的功能,但一般的操作是沒有問題的。

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語言編寫一個(gè)多功能計(jì)算器的詳細(xì)內(nèi)容,更多關(guān)于C語言計(jì)算器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 關(guān)于C語言位運(yùn)算的簡(jiǎn)單示例

    關(guān)于C語言位運(yùn)算的簡(jiǎn)單示例

    這篇文章主要介紹了關(guān)于C語言位運(yùn)算的簡(jiǎn)單示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • C++ 實(shí)現(xiàn)L2-002 鏈表去重

    C++ 實(shí)現(xiàn)L2-002 鏈表去重

    這篇文章主要介紹了C++ 實(shí)現(xiàn)L2-002 鏈表去重,本文通過簡(jiǎn)要的案例,解題思路講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Qt實(shí)現(xiàn)簡(jiǎn)單的TCP通信

    Qt實(shí)現(xiàn)簡(jiǎn)單的TCP通信

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)簡(jiǎn)單的TCP通信,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C語言簡(jiǎn)明分析指針與引用的具體用法

    C語言簡(jiǎn)明分析指針與引用的具體用法

    指針是一個(gè)實(shí)體,引用是一個(gè)別名;在匯編上,引用的底層是以指針的方式實(shí)現(xiàn)的,定義一個(gè)引用變量,相當(dāng)于定義了一個(gè)指針,然后把引用內(nèi)存的地址寫到這個(gè)指針里面,當(dāng)通過引用變量修改它所引用的內(nèi)存時(shí),它先訪問了指針里面的地址,然后在這個(gè)地址的內(nèi)存里面對(duì)值進(jìn)行修改
    2022-05-05
  • C++實(shí)現(xiàn)LeetCode(58.求末尾單詞的長(zhǎng)度)

    C++實(shí)現(xiàn)LeetCode(58.求末尾單詞的長(zhǎng)度)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(58.求末尾單詞的長(zhǎng)度),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++實(shí)現(xiàn)線性表順序存儲(chǔ)的示例代碼

    C++實(shí)現(xiàn)線性表順序存儲(chǔ)的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)線性表順序存儲(chǔ)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下
    2023-03-03
  • C語言編程簡(jiǎn)單卻重要的數(shù)據(jù)結(jié)構(gòu)順序表全面講解

    C語言編程簡(jiǎn)單卻重要的數(shù)據(jù)結(jié)構(gòu)順序表全面講解

    這篇文章主要為大家介紹了C語言編程中非常簡(jiǎn)單卻又非常重要的數(shù)據(jù)結(jié)構(gòu)順序表的全面講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-10-10
  • C語言goto的應(yīng)用舉例以及詳解

    C語言goto的應(yīng)用舉例以及詳解

    goto的用法就是改變程序執(zhí)行的順序,從某個(gè)地方跳轉(zhuǎn)到你標(biāo)志的地方,下面這篇文章主要給大家介紹了關(guān)于C語言goto的應(yīng)用舉例及詳解的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • C++二叉樹的創(chuàng)建及遍歷詳情

    C++二叉樹的創(chuàng)建及遍歷詳情

    這篇文章主要介紹了C++二叉樹的創(chuàng)建及遍歷詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)有所幫助
    2022-07-07
  • c語言二進(jìn)制數(shù)按位輸出示例

    c語言二進(jìn)制數(shù)按位輸出示例

    這篇文章主要介紹了c語言二進(jìn)制數(shù)按位輸出示例,需要的朋友可以參考下
    2014-03-03

最新評(píng)論