■このコードは手抜きです
・ゼロ割り算をガードしていません。
・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 を記述する】という
ルールがありますが
わかりやすいですか?
一般にネスト(字下げ)が深くなるほど
コードは難解になるとされています。