質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

2784閲覧

複数のテストの点数を入力し、0点以上10点未満は何人、と細かく表示させたい

papapa

総合スコア11

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2021/07/19 07:13

編集2021/07/19 15:59

前提・実現したいこと

タイトル通りです
下のように表示させたいです
ですが、うまくいきません。。。

テストの点数を入力してください。
32
33
33
34
5
0点以上 10点未満 = 1人
10点以上 20点未満 = 0人
20点以上 30点未満 = 0人
30点以上 40点未満 = 4人
40点以上 50点未満 = 0人
50点以上 60点未満 = 0人
60点以上 70点未満 = 0人
70点以上 80点未満 = 0人
80点以上 90点未満 = 0人
90点以上100点未満 = 0人
100点 = 0人

合計 = 5人

該当のソースコード

c

1 #include <stdio.h> 2 3int main(void) 4{ 5int test[100]; 6int i; 7int a[10]={0}; 8 9 10printf("テストの点数を入力してください。\n"); 11scanf("%d",&test[i]); 12 13for(i=0;i<101;i++){ 14 if(test>=0&&test<10){a[0]++;} 15 if(test>=10&&test<20){a[1]++;} 16 if(test>=20&&test<30){a[2]++;} 17 if(test>=30&&test<40){a[3]++;} 18 if(test>=40&&test<50){a[4]++;} 19 if(test>=50&&test<60){a[5]++;} 20 if(test>=60&&test<70){a[6]++;} 21 if(test>=70&&test<80){a[7]++;} 22 if(test>=80&&test<90){a[8]++;} 23 if(test>=90&&test<100){a[9]++;} 24 if(test==100){a[10]++;} 25} 26 27printf(" 0点以上10点未満 =%d人\n",a[0]); 28printf(" 10点以上20点未満 =%d人\n",a[1]); 29printf(" 20点以上30点未満 =%d人\n",a[2]); 30printf(" 30点以上40点未満 =%d人\n",a[3]); 31printf(" 40点以上50点未満 =%d人\n",a[4]); 32printf(" 50点以上60点未満 =%d人\n",a[5]); 33printf(" 60点以上70点未満 =%d人\n",a[6]); 34printf(" 70点以上80点未満 =%d人\n",a[7]); 35printf(" 90点以上100点未満 =%d人\n",a[8]); 36printf("100点        =%d人\n",a[9]); 37printf("-----------------------------\n"); 38printf("合計 =%d人",a[0]+a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8]+a[9]);

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

1T2R3M4

2021/07/19 07:24

2人目以降の点数はどうやって取得していますか。
BeatStar

2021/07/19 08:04

インデント(Tabキーや半角スペースでやるアレ)ぐらいは入れましょう。 今のままでは読みづらいです。
Zuishin

2021/07/20 01:10

配列が苦手なら勉強すればいいじゃないですか。 a1 と書くのも a[1] と書くのもいっしょでしょう。
dodox86

2021/07/20 02:38

[2021/07/20 00:59]の質問編集を読んで: いや、コードを書き直せば良いというものではないです。自動的に添削してもらえる訳じゃないですよ。ちゃんと応対しましょう。
guest

回答4

0

コードを書くことに着手するよりもまえに,まずは「どんな処理をどんな順に実施していけばこの話を達成できるのか」という筋道をまともに考えた方が良いと見受ける.


例えば,以下のように考えたりする.

(1)必要な処理にはどんなものがあるのだろう?

  • 点数を1つ入力してもらう処理が必要だ
  • 入力された点数に応じて度数分布データを更新する処理も必要
  • 度数分布データを表示する処理ももちろん必要だよね.
  • プログラムを終わらせるのか,また次の入力を受け付けるのか? を決める方法が無いといかんよね.

ものすごーくざっくり言えば,これらの要素は,こいつらをそれぞれ関数としてでも用意すればいいんじゃないかな的な話に対応.

(2)どんな順で処理を行えばよいのだろうか?

  1. 初期処理.(度数分布データの値を全部0にしとくとか,そういう.)
  2. とりあえず1個入力
  3. 終了判定.例えば「入力値の値が何か特別な値XXXだったら,終了という意味」とかいうルールを決めて,終了条件を満たすなら6.に進む
  4. 入力値を用いて度数分布データを更新
  5. 次の入力のために2.に戻る
  6. 度数分布データを表示
  7. プログラム終了

ざっくり言えば,これがmain関数内の処理フローに相当.

(3)このプログラムってどんなデータが必要?

  • 複数の入力値を記憶すべきだろうか?
    各入力値は度数分布データに反映したらもう要らないハズだ.
    各入力値が58点だったとかそういう具体的な値を使う処理は以降には無いのだから,全ての入力値を律儀に覚えておく必要は無い.
  • 度数分布データは何はともあれ必要だよね.
    これは上記処理順序の1.~6.までの間存在し続けて,更新されるデータだ.
    段階は10段階必要だから,10個の数値データだ.
    (配列にすると自然だし楽だろうが,そのことはmustというわけではない.とにかく要件的には10個あればいい.)

↑の話を素直にコード化すれば,こんな形↓が書ける.
(1)で列挙した要素を関数とし,
(2)のフローをmain関数内に書いた.

あとは(どこかにミスが無ければ)各関数の中身を(好きなように)実装すればよい.

…という形(各処理の具体実装は無いけども,それらは何をして,結果としてどんなデータが得られるのか? という話だけは定まった状態)をまずは作ることをやると良いと思う.
(「穴埋め問題」状態のコードを作る,とでも言うか.)

この疑似コード例では,度数分布データを配列Histogramで表現しているが,これが個別の10個の変数だったとしても,main関数内のコードは一切の影響を受けない.
このデータを直接扱っているのは,UpdateHistogram, ShowHistogram の2つの関数の内側だけだからだ.
(こういう形にしておけば,「最初にとりあえず個別の10個で実装してみて→次に配列版に挑戦してみる」とかいうことをするにしても,変更範囲は明確.)

C

1//度数分布データ.※ここでは話を簡単にするために外部変数としている. 2int Histogram[10] = { 0 }; 3 4//点数を1個入力してもらう処理. 5//入力された値を返す. 6int Input(){ /*scanfなり何なりで入力された値をreturnする*/ } 7 8//度数分布データの更新処理. 9//引数に,入力された点数を渡す. 10void UpdateHistogram( int input_val ){ /*引数値に応じて,配列 Histogram のどれかの要素を1増やす*/ } 11 12//度数分布データの表示処理 13void ShowHistogram(){ /*配列 Histogram の内容を仕様通りに表示する*/ } 14 15//終了すべきか?の判定処理. 16//引数に,入力された点数を渡す. 17//引数が「終了すべき値」なら1を,そうでないなら0を返す. 18int IsFinishRequest( int input_val ) 19{ //※この例では,負の値か100より大きい値のときは終了っていうルール 20 return ( (input_val<0 || 100<input_val) ? 1 : 0 ); 21} 22 23//---------- 24//main 25int main( void ) 26{ 27 //1.初期処理 28 // (Histogramは全0に初期化できているので,この例では特にやることはない) 29 30 while( 1 ) //繰り返す( "5.次の入力のために2.に戻る" に相当 ) 31 { 32 //2.入力 33 int input_val = Input(); 34 35 //3.終了判定 36 if( IsFinishRequest(input_val) == 1 )break; 37 38 //4.度数分布データを更新 39 UpdateHistogram( input_val ); 40 } 41 42 //6.度数分布データを表示 43 ShowHistogram(); 44 45 //7.プログラム終了 46 return 0; 47}

投稿2021/07/20 01:06

編集2021/07/20 01:34
fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/07/20 01:39

どんな処理をどんな順序でやってくのか,どんなデータがあるのか? という明確なビジョンが先に無ければコードを書けるわけがない,っていう至極単純な話. 「データを配列で持つかどうか?」なんてのは実装の具体的な詳細でしかなく,話の本筋ではない. その影響範囲をある範囲内に閉じ込めておけば,後から(範囲外に影響を及ぼさずに)そこだけ変更できる.
fana

2021/07/21 01:03

素で > 段階は10段階 って書いてたけど,「100点」もあるから11段階ですやん^^
guest

0

ベストアンサー

1個しかデータが入れられていないのは分かっているんですが、何個入れるか分からない状態でのプログラムの書き方がわからなくて、、

・最初に個数を入力してから、その個数分のデータを処理する例。

c

1 int n, score; 2 scanf("%d", &n); 3 for (int i = 0; i < n; i++) { 4 scanf("%d", &score); 5 printf("%d\n", score * 2); 6 }

・データの範囲外の値があれば終わりとする例

c

1 int score; 2 while (1) { 3 scanf("%d", &score); // score は 0 から 100 まで 4 if (score < 0) break; 5 printf("%d\n", score * 2); 6 }

・読み込めなかったら終わりとする例

c

1 int score; 2 while (scanf("%d", &score) == 1) 3 printf("%d\n", score * 2);

入力がキーボードの場合、Linux では「行頭で Ctrl-D」または「Ctrl-D Ctrl-D」、
Windows では「行頭で Ctrl-Z Enter」で終わりを表します。

点数の分類は、0点代、10点台、...、90点台、100点 の 11 通りです。
質問のコードでは「printf(" 80点以上」がありません。

C

1 #include <stdio.h> 2 3int main(void) 4{ 5 int freq[11] = { 0 }; 6 int num = 0; 7 int score; 8 9 printf("テストの点数を入力してください。\n"); 10 while (scanf("%d", &score) == 1 && score >= 0 && score <= 100) { 11 freq[score / 10]++; 12 num++; 13 } 14 int a = 0; 15 for (int i = 0; i < 10; i++) { 16 printf(" %2d点以上%2d点未満 = %d人\n", a, a+10, freq[i]); 17 a += 10; 18 } 19 printf("100点 = %d人\n", freq[10]); 20 printf("-----------------------------\n"); 21 printf("合計 = %d人\n", num); 22}

これを参考に配列と for文の勉強をしてください。

投稿2021/07/20 18:34

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

まず、私の過去回答を参考にしてください。
(必ず読んでください!!!!!)

そして、コードを読みましょう。

コードを読むコツは『一行レベルで、この行が何をしているかを考えながら読む』です。

今回の場合、

C

1#include <stdio.h> 2 3int main(void) 4{ 5 6// 変数宣言(1) 7int test; 8int i; 9 10// 変数宣言(2) 11int a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10; 12 13 14// 初期設定 15a0=0; 16a1=0; 17a2=0; 18a3=0; 19a4=0; 20a5=0; 21a6=0; 22a7=0; 23a8=0; 24a9=0; 25a10=0; 26 27// 入力を促す 28printf("テストの点数を入力してください。\n"); 29// 変数 test に一個分の整数データを受け取って設定する 30scanf("%d",&test); 31 32// 変数iの初期値: 0, iが5以下の間, インクリメント( +1 )しながら繰り返す 33// => つまり5回繰り返す 34for(i=0;i<5;i++){ 35// testが 0 以上, 10未満なら, 変数 a1 をインクリメント 36if(test>=0&&test<10){a0++;} 37// testが 10 以上, 20未満なら, 変数 a2 をインクリメント 38if(test>=10&&test<20){a1++;} 39// testが 20 以上, 30未満なら, 変数 a3 をインクリメント 40if(test>=20&&test<30){a2++;} 41// ... 42if(test>=30&&test<40){a3++;} 43if(test>=40&&test<50){a4++;} 44if(test>=50&&test<60){a5++;} 45if(test>=60&&test<70){a6++;} 46if(test>=70&&test<80){a7++;} 47if(test>=80&&test<90){a8++;} 48if(test>=90&&test<100){a9++;} 49if(test==100){a10++;} 50} 51// 『○点以上△点未満 = 人数』のように出力する 52printf(" 0点以上10点未満 =%d人\n",a0); 53printf(" 10点以上20点未満 =%d人\n",a1); 54printf(" 20点以上30点未満 =%d人\n",a2); 55printf(" 30点以上40点未満 =%d人\n",a3); 56printf(" 40点以上50点未満 =%d人\n",a4); 57printf(" 50点以上60点未満 =%d人\n",a5); 58printf(" 60点以上70点未満 =%d人\n",a6); 59printf(" 70点以上80点未満 =%d人\n",a7); 60printf(" 90点以上100点未満 =%d人\n",a8); 61printf("100点        =%d人\n",a9); 62printf("-----------------------------\n"); 63printf("合計 =%d人",i); 64 65// main関数から抜ける 66return 0; 67}

これを現実世界のノートでも、PCのテキストファイルにでも、
自分が読み書きできる人間用の言語で書き下す。( as 疑似コード )

0. 変数宣言と初期化 1. 一個分の整数データを受け取り、変数testにセット 2. 以下を5回繰り返す 2.1. testが0以上10未満なら 2.1.1. 変数 a1 をインクリメント 2.2. (そうじゃなくて) testが10以上20未満なら 2.2.1. 変数a2をインクリメント 2.3. (そうじゃなくて) testが20以上30未満なら 2.2.1. 変数a3をインクリメント ... 3. 結果を出力する

ですね。

これを現実世界で手作業でやってみる。(つまり、上記の疑似コードを手作業でシミュレーションしてみる)
脳内でもいいです。

そうすると、『あれ? なんで俺、(1) では1個しかデータを撮っていないんだ?』と気づきませんか?

それと、int a1, a2, a3, a4 ...; のように宣言していますが、これだとfor文で回せません。
(できなくはないが面倒すぎる…)

データ列 a1, a2, a3 ... は『テストの点数』であることは同じ(点数や『誰の点数か』とかが違うだけ)
なので、変数ではなく配列にすればいいです。

そうすれば、a[0], a[1], a[2] ... とアクセスできるため、for文でも直接使えます。

また、デバッグ方法も覚えましょう。

プログラミングをする場合は必須の技術です。


[追記1]

あと配列の書き方が苦手で、

苦手でも理解しましょう。

プログラミングっていうのは『こう書けばいい』ではなく、「現実世界でのシミュレーション」です。

一応配列を使わなくても出来ますが、相当面倒ですよ?

「マッチを擦るのが苦手で……でも料理をするために火を使いたいです。無人島なのでガスコンロさえありません。かろうじてマッチだけが手元にありました」

みたいなものです。

確かに木を擦っても火は付きますが、相当面倒です。
1~2分じゃないですよ? あれは1時間とかかかるっぽいです。
(天候によってはさらにかかる模様)

それをマッチを擦るのが苦手だからと避けていてはできませんよ。

ましてやプログラミングっていうのは大抵、複数人で開発するようです。

一人がわかりづらい書き方をしていると、みんなが迷惑します。

プログラミングっていうのは書いて終わり……ではありません。
デバッグやテストまで含みます。
そうなると相当な労力を使います。

道具は人間が使いやすいようにデザインされています。(少なくとも今風のは)

道具も使いようです。

1個しかデータが入れられていないのは分かっているんですが、何個入れるか分からない状態でのプログラムの書き方がわからなくて、、

今回は、C言語ですよね。

C++としてであれば、std::vectorとかが使えますが、今回はC言語なのでちょっと面倒。

C言語の配列は要素数を指定しないといけないので、「あえて大きく取ります」。

問題文とかの仕様上で、「Nは10以下」とかみたいな条件があるはずなので、その上限まで使えるように、
たとえば MAX+1 とかみたいな感じでデカく取る。

そして、入力値 N (実際に使う要素数) を受け取るはずなので、それを変数とかに確保しておく。
学校の課題とかで指定されていない場合は、入力された分インクリメントして数え上げ、
それの最終的な個数をN とするとか。


[追記2]

まずは基礎をやりましょう

基礎をないがしろにする人は大成しません。
これは100%断言できます

今の状態は『包丁の使い方がまったくわかりませんが、かつら剥きを極めたいです。やり方を教えてください』というようなものです。

かつら剥きって、相当難易度高いと思います。

みじん切りや角切りとかなら適当に切っても出来そうですが、かつら剥きはうすーーーーく切らないといけませんし、続けないといけません。

でも包丁の使い方すらわかっていないと、下手すれば自分の手や指を切りますし、
良くても、かつら剥きは厳しいと思います。

確かに包丁の使い方程度ならほぼ一瞬で教えることが出来ますが、この包丁の使い方が
たとえばこの道ウン十年の人しかできないっていうようなレベルのものだとどうでしょうか。

そもそもその基礎である包丁の使い方ですら教えきることができませんね。

なので「基礎である、包丁の使い方からやるように!!」と言っても、

「俺様はかつら剥きがしたいんだ!!! 包丁の使い方ぐらい、簡単に教えろよ!!!」というようなものです。

「あー、君、無理だからやめといた方がいいよ?」と言いたくなりますよね。

そういうレベルです。

まずは基礎からやり直しましょう

基礎が出来て初めて応用が出来るのです。

それと、プログラミングは『書いて終わり』ではありません。

上記で挙げた私の過去回答を読みましたか?

そこにも書いていますが、プログラミングはデバッグまで含むです。

「DIYが趣味だ」だと言う人が「椅子を作ったけど高さが合わないから誰か、修繕してくれ」
や「椅子を作りたいんだけど誰か設計図書いてくれ」と言うようなものです。

「それは本当にDIYが趣味と言えるのか?」と思いますよね。

そういうレベルです。

投稿2021/07/19 08:23

編集2021/07/21 03:05
BeatStar

総合スコア4962

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

papapa

2021/07/19 10:10

1個しかデータが入れられていないのは分かっているんですが、何個入れるか分からない状態でのプログラムの書き方がわからなくて、、 あと配列の書き方が苦手で、、
nob.

2021/07/21 02:21

横から失礼します。 1個のデータを入力する → 点数により分類する → 該当の件数を+1する → 次のデータ入力へ とすれば、質問者さんがすでにお書きになっている int a[10]={0}; (正しくはa[11] ?) 以外の配列は必要ないように思えるのですが? 提示されたコードは100人分の点数を覚えておくように書かれているようですが、 入力されたデータを全て覚えておく必要があるのですか?
guest

0

コードを見るに、点数の入力は一個しか行ってません。
まずはこれを複数行うようにしましょう。

投稿2021/07/19 07:41

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

papapa

2021/07/19 09:39

複数するにはint test1,test2みたいにしないとだめですか?
y_waiwai

2021/07/19 09:43

そこは、配列を使いましょう コード中でも、a0~a10という変数を使ってますが、これも配列にしてしまうほうがいいかと思います int a[10]; これで、a[0]からa[9] のint変数が使えます
papapa

2021/07/19 10:24

配列を使うのが苦手なのですが、配列にしてどうするのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問