【C言語サンプル】
根性のない電卓

このコードは手抜きです

・ゼロ割り算をガードしていません。
・1+1は出来ますが、1+1+1は出来ません
・+-*/の四則演算しか出来ません
・演算子が2文字以上の考慮はしていません(<<とか)

このコードで学習できること

・switch文の複文(マルチステートメント)
・コンパイラ別の条件コンパイル
・標準入力終了判定
・空行判定
・sscanfに字句解析をお任せする
・breakとcontinueを使って字下げを浅くする(早期リターン)

根性のない電卓(C言語サンプル)

#include <stdio.h>
int     calc(int num1,char op,int num2){
    switch(op){
    case    '+':    return  num1+num2;
    case    '-':    return  num1-num2;
    case    '*':    return  num1*num2;
    case    '/':    return  num1/num2; 
    }
    fprintf(stderr,"未サポートの演算子 %c\n",op);
    return  -1;
}
int main(void){
#if __linux__    
    printf("Ctrl dか空行で終了\n");
#elif (_WIN32 || _WIN64)
    printf("Ctrl zか空行で終了\n");
#else
    #error  "「標準入力終了」でググって下さい"
#endif
    for(;;){ 
        printf("数字 演算子 数字を入れてね");
        char    buf[BUFSIZ];
        if(fgets(buf,BUFSIZ,stdin) == NULL){
            break;      //標準入力終了でループ終了
        }
        if(buf[0] == '\n'){
            break;      //空行でループ終了
        }
        int     num1,num2;
        char    op;
        int     ret = sscanf(buf,"%d %c %d",&num1,&op,&num2);
        if(ret != 3){   //3単語無い時は再入力 
            continue ;  //ループ続行 
        }
        printf("答え %d\n",calc(num1,op,num2));
    }
}

コンパイル&実行してみて下さい。

根性のある人は

「C言語 逆ポーランド記法」でググって実装してみて下さい。

聖典書籍 「プログラミング言語C」では、
逆ポーランド記法が詳細解説されています。

コーディングルールに従った四則演算

int     calc(int num1,char op,int num2){
    //変数宣言
    int     ret ; 
    //とりあえず初期化
    ret = 0; 
    //複文禁止、関数出口は一つ,case は一段字下げ
    switch(op){
        case    '+':    
            ret = num1+num2;
            break;
        case    '-':    
            ret = num1-num2;
            break;
        case    '*':    
            ret = num1*num2;
            break;
        case    '/':    
            ret = num1*num2;
        default:
            fprintf(stderr,"未サポートの演算子 %c\n",op);
            ret  -1;
            break ;
    }
    return  ret ;
}


わかりやすいですか?
ちょっと2か所バグってるの分かりますか?

コーディングルールで複文(マルチステートメント)を禁止している
プロジェクトは多くありますが、
がちがちにルールで縛ると
このようにコードがわかりにくくなる場合があります。

MISRA-C2012 R15.7 の誤解釈

int main(void){
    printf("Ctrl dか空行で終了\n");
    for(;;){ 
        printf("数字 演算子 数字を入れてね");
        char    buf[BUFSIZ];
        if(fgets(buf,BUFSIZ,stdin) != NULL){
            if(buf[0] != '\n'){
                int     num1,num2;
                char    op;
                int     ret = sscanf(buf,"%d %c %d",&num1,&op,&num2);
                if(ret == 3){   //3単語無い時は再入力 
                    printf("答え %d\n",calc(num1,op,num2));
                } else {
                    continue ;  //ループ続行
                }
            } else {
                break;      //空行でループ終了
            }
        } else {
            break;      //標準入力終了でループ終了
        }
    }
}


MISRA-C2012 R15.7 のよくある誤解釈
〇すべてのif … else if構文は、else文で終了しなければならない
✖すべてのif構文は、else文で終了しなければならない

独自のローカルルールでも
【if文を記述したら必ずelse を記述する】という
ルールがありますが
わかりやすいですか?

一般にネスト(字下げ)が深くなるほど
コードは難解になるとされています。