[1] 授業単元:C言語
[2] 問題文
★下記の仕様を満たすプログラムをC言語で作成する。
【仕様】図形の面積学習簡易プログラム
▼「三角形の面積」「平行四辺形の面積」「台形の面積」を求める問題を
ランダムに出題する。オリジナル関数を作って処理すること。
▼例えば「三角形の面積」の場合、「底辺が4、高さが7の三角形の面積は?」
と出題する。与えるべき数値(簡単なため数値は1~9でよい)は全てランダムに表示する。▼回答を入力させ、正解の場合は「よくできました」と表示し、不正解の場合は
「まちがいです」という文を表示する。
▼「続けますか?」と表示し、「はい」なら出題する。「いいえ」ならばこれまでの正解率を計算する。正解率に応じて80%以上ならA、70~79%ならB、60~69%ならC、59%以下ならDと表示する。
[3] 環境
OS: Windows xp
if文、for文,関数プロトタイプ宣言、戻り値
引数はやりました。標準ライブラリ関数と配列はやってないです・・・
正解率の出し方が分からないので誰か教えてください。
うまくプログラムがかけないのですが、アドバイスをお願いします。
とりあえず作って見ました。ソースは添付してあります。
課題が出てるのですが分からなくて・・・
Re:課題が出てるのですが分からなくて・・・
正解率なら
(正解数/出題数)*100でいいのではないでしょうか
それぞれ変数を用意して
正解数は初期値を0として”よくできました。”と表示しているところで+1
出題数は初期値を0とするなら正解率計算前に、1なら続けるを選択後に+1
するなどすればいいかと思います
また数値を入力する部分のループが抜けられないのですがいいのでしょうか
まだ途中だから後で修正するのかと思いますが…
これはあまり気にしなくてもいいですが
個人的に正解率は続けるか選択前に表示してほしいような
(正解数/出題数)*100でいいのではないでしょうか
それぞれ変数を用意して
正解数は初期値を0として”よくできました。”と表示しているところで+1
出題数は初期値を0とするなら正解率計算前に、1なら続けるを選択後に+1
するなどすればいいかと思います
また数値を入力する部分のループが抜けられないのですがいいのでしょうか
まだ途中だから後で修正するのかと思いますが…
これはあまり気にしなくてもいいですが
個人的に正解率は続けるか選択前に表示してほしいような
Re:課題が出てるのですが分からなくて・・・
ちょっと添削してみました。
double (*func[3])(void)={sankakukei,heikou,daikei}; int n,rnd,num1,ans; char res; srand(time(NULL)); for(n=0; n<10; n++){ //ここで出題数を数えなければならない ans =func[rand()%3](); //無限ループになっている。 for(;;){ printf("解答\n"); //%fが間違い。回答はdouble型で受け取る必要があるのでは? scanf("%f",&num1); } if(ans == num1)//正解数をここで数えなければならない printf("よくできました。\n"); else printf("間違いです。\n"); //このままでは無限ループ for(;;){ printf("続けますか?はい=1,いいえ=2\n"); //前回scanfで入力した時の改行コードが自動で入るのでこれではだめ scanf("%c",&res); //文字コードの1と数字の1は違う if(res == 1) continue; else//ループから抜けないといけない。 printf("正解率は\n"); //xに正解率をいれなければならない。 //ここはループの外でなければならない if(x >= 80) printf("Aです。\n"); else if(x >= 70 && x < 80) printf("Bです。\n"); else if(x < 60)//60~70がない printf("Cです。\n"); } } return 0; }
Re:課題が出てるのですが分からなくて・・・
正解率は
>(正解数/出題数)*100
でいいと思います。
乱数を0~2でだして
>(正解数/出題数)*100
でいいと思います。
double (*func[3])(void)={sankakukei,heikou,daikei}; ... ans =func[rand()%3]();は
乱数を0~2でだして
if() else if() else()を利用するなり、switchを利用するなりして、問題を出すのを分岐したほうが簡単なきがするのですが・・・
ans =func[rand()%3]();はエラーはでないのでしょうか?
Re:課題が出てるのですが分からなくて・・・
なんだか気になったので色々試してみました。
0%
100%
50%
最後の計算式は普段私が使っている式なのですが、わかりにくくなるのが目に見えてますね・・・
par,Q,Aをそれぞれdouble型にして、%dを%fにしたところ正しい計算結果が得られましたが、
50.0000%などのように表示されてしまいます。
int main(void){ int par; int Q=10,A=5; //10問中5問正解した par = (A/Q)*100; //50%のはず printf("%d%\n",par); par = (A/A)*100; printf("%d%\n",par); //100% par = A*100/Q; //50% printf("%d%\n",par); }実行結果
0%
100%
50%
最後の計算式は普段私が使っている式なのですが、わかりにくくなるのが目に見えてますね・・・
par,Q,Aをそれぞれdouble型にして、%dを%fにしたところ正しい計算結果が得られましたが、
50.0000%などのように表示されてしまいます。
Re:課題が出てるのですが分からなくて・・・
ansとnum1の型はintでいいのでしょうか? func関数の戻り値はdouble型になっていますよ。
仮に双方をdouble型にした場合、両者が等しいかどうかを == で
検査するのはちょっと危険です。
浮動小数点数の計算にはなにがしかの誤差を伴います。
例えば、ご自分では28.0という値のつもりでいても、
実際には27.9999999だったり28.0000001だったりするかもしれません。
そうすると、ご自分では正解のつもりが不正解とみなされてしまうことになります。
というわけで、あらかじめ許容範囲を決めておいて、
その範囲内ならば等しいとみなす、という処理が必要になろうかと思います。
仮に双方をdouble型にした場合、両者が等しいかどうかを == で
検査するのはちょっと危険です。
浮動小数点数の計算にはなにがしかの誤差を伴います。
例えば、ご自分では28.0という値のつもりでいても、
実際には27.9999999だったり28.0000001だったりするかもしれません。
そうすると、ご自分では正解のつもりが不正解とみなされてしまうことになります。
というわけで、あらかじめ許容範囲を決めておいて、
その範囲内ならば等しいとみなす、という処理が必要になろうかと思います。
Re:課題が出てるのですが分からなくて・・・
>管理人さん
ほほ~こんな風に使えるのですね。
なんか関数名と()が離れ離れになってるように見えてかなり違和感がありました。。
すみません。本題からそれました|ミサッ
ほほ~こんな風に使えるのですね。
なんか関数名と()が離れ離れになってるように見えてかなり違和感がありました。。
すみません。本題からそれました|ミサッ
Re:課題が出てるのですが分からなくて・・・
boxさんの仰るとおり、double型は一筋縄では比較出来ないので、
double型を比較する為の関数を作ってみました。
比較したい変数を二つ最初に引数としてわたし、第三引数にその許容誤差値を渡します。
0が返ってきたら一致、-1なら不一致です。
gosaは適当に0.00001とか渡せばいいと思います。
この辺は最初に決まりを作ればいいかと思います。
double型を比較する為の関数を作ってみました。
比較したい変数を二つ最初に引数としてわたし、第三引数にその許容誤差値を渡します。
//0なら一致、-1なら不一致 int judge(double a, double b, double gosa){ double c; c = a-b;//差をとる if(c<0)//負の値なら c*=-1;//正に if(c<gosa)//誤差範囲なら return 0;//一致 else//それ以外なら return -1;//不一致 }
0が返ってきたら一致、-1なら不一致です。
gosaは適当に0.00001とか渡せばいいと思います。
この辺は最初に決まりを作ればいいかと思います。
Re:課題が出てるのですが分からなくて・・・
追記
この+1が必要ではないでしょうか。
double sankakukei(void){//三角形
int a,h;
printf("底辺が%d,高さが%dの三角形の面積は?\n",a=(rand()%3)+1,h=(rand()%3)+1);
return a*h/2.0;
}
この+1が必要ではないでしょうか。