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

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

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

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

Q&A

4回答

414閲覧

score[2][20]を用いて英語と数学を分けて得点分布 することができるでしょうか

0fg3873t38k3z3e

総合スコア0

C

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

0グッド

0クリップ

投稿2024/03/23 14:41

問題 4
20人2科目の点数の集計
ある学校で英語と数学の試験を実施し、試験点数は
実数で0~100点で採点した。この試験の20人分の点数を
入力させ、下記のように科目ごとの得点分布を集計
するプログラムを作成しなさい。結果の表示例は
以下のとおり。

        Eng   Math
0以上 20未満  0 2
20以上 40未満 7 3
40以上 60未満 8 3
60以上 80未満 4 8
80以上 100未満 0 2
100点      1    2  

このプログラムを途中まで作成しましたが、
英語と数学の点数をscore[2][20]で表そうとすると
得点分布のときに英語と数学に分けることができま
せん。
score[2][20]を用いて英語と数学を分けて得点分布
することができるでしょうか
#include <stdio.h>
#define HANI 6

int main(int argc, char** argv) {
printf(" Eng Math\n ");
double Point[2][20];
int score[2][20];
int Eng[6];
//Eng[20], Math[20];
int i,j,k;
//printf("英語");
for (k = 0;k<6;k++) {
Eng[k] = 0;
}
for (i = 0;i <20;i++) {
for (j = 0;j < 2;j++) {
printf("%d人目", i+1);
scanf("%d", &score[j][i]);
if (score[0][i] < 20) { Eng[0]++; }
else if (score[0][i] < 40) { Eng[1]++; }
else if (score[0][i] < 60) { Eng[2]++; }
else if (score[0][i] < 80) { Eng[3]++; }
else if (score[0][i] < 100) { Eng[4]++; }
else if (score[0][i] == 100 {Eng[5]++;}
}

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

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

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

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

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

jimbe

2024/03/23 17:00 編集

>英語と数学の点数をscore[2][20]で表そうとすると >得点分布のときに英語と数学に分けることができま >せん。 何故 score[2][20] で表そうとされているのでしょうか。 コメントにされている //Eng[20], Math[20]; を用いた方が先に進めると思いますが。 もし2次元配列がよく分からないということでしたら、検索して各記事を読んでみては如何でしょう。 [google検索: c 2次元配列] https://www.google.com/search?q=c+2%E6%AC%A1%E5%85%83%E9%85%8D%E5%88%97 また、score を1次元配列で [40] にして 0~19 を英語 20~39 を数学 にするとか、2つずつを1人分として 0 を1人目の英語 1 を1人目の数学 2 を2人目の英語 … 38 を20人目の英語 39 を20人目の数学 とする(偶数番目が英語、奇数番目が数学)等の方法もあります。 更には、分布を数えるだけなら score に保存する必要は無く、入力した値を if に通して Eng/Math 配列を更新したら捨ててしまっても良いようです。
fana

2024/03/25 02:34

> 20人分の点数を入力させ ここ,入力の順序を明言した方が良いのでは. そこも自由に決められるならば, 「1教科分の処理」全体を2回やる が最も単純に済むだろうし. あと,こういうのは 入力とそれに対する出力の例 をいくつか(最低1例)示すと,回答者全員が同じ入力を使うように仕向けることができて良いんじゃないかな. (各回答がてんでバラバラな入出力の結果を示す状態だと,あなたも判断し難いでしょう)
fana

2024/03/25 04:32

ところで, > 実数で0~100点で採点した の「実数で」とは,「30.276点」みたいな得点があり得るということを指しているのでしょうか? (ごく普通に整数なのであれば,わざわざ「実数で~」とか付けて書かないと思うので,ちょっと気になる)
guest

回答4

0

一度int型変数に代入してscore[i][j]に代入してはどうでしょうか?

c

1#include <stdio.h> 2 3// 生徒数やランク分けが変わった際、ここを修正すると対応できます 4#define STUDENTS_COUNT 20 // 生徒数 5#define MAX_POINT 100 6#define RANK_STEP 20 7#define RANK_COUNT (MAX_POINT / RANK_STEP + 1) // ランク数 8 9// 科目を示す列挙型(最後のSUBJECTS_COUNTは科目数) 10// これを作っておくと、後々にデータの参照が楽になります 11// 今回は英語(EN)、数学(MA)だけにしていますが、 12// 国語(JA)、理科(SC)、社会(SS)なども定義しておくと、 13// 更に便利になると思います 14enum SUBJECTS {EN, MA, SUBJECTS_COUNT}; 15 16int scores[STUDENTS_COUNT][SUBJECTS_COUNT]; // 生徒数 x 科目数の配列 17int distributions[RANK_COUNT][SUBJECTS_COUNT]; // 科目数 x ランク数の配列 18 19void print_data () { 20 // 科目情報出力 21 printf("\t\tEng\tMath\n"); 22 // 英語と数学の度数分布を取得 23 int score_lower, score_upper; 24 int score_english, score_math; 25 for (int i = 0; i < RANK_COUNT; i ++) { 26 score_lower = i * RANK_STEP; // ランク帯の下限値 27 score_upper = (i + 1) * RANK_STEP; // ランク帯の上限値 28 score_english = distributions[i][EN]; // 英語の度数 29 score_math = distributions[i][MA]; // 数学の度数 30 if (i < RANK_COUNT - 1) { 31 printf("%d以上\t%d未満\t%d\t%d\n", score_lower, score_upper, score_english, score_math); 32 } else { 33 printf("%d点\t\t%d\t%d\n", score_lower, score_english, score_math); 34 } 35 } 36} 37 38int main (void) { 39 int students_index; // 生徒数のカウンタ 40 int subjects_index; // 科目数のカウンタ 41 int rank_index; // ランク数のカウンタ 42 int score = 0; // 標準入力からの代入先 43 // 生徒数だけループ 44 for (students_index = 0; students_index < STUDENTS_COUNT; students_index ++) { 45 printf("%d人目\n", students_index + 1); // 何人目か表示する 46 // 科目数だけループ 47 for (subjects_index = 0; subjects_index < SUBJECTS_COUNT; subjects_index ++) { 48 scanf("%d", &score); // 標準入力から得点を取得する 49 scores[students_index][subjects_index] = score; // 任意の生徒・科目の得点を変更 50 rank_index = scores[students_index][subjects_index] / RANK_STEP; // ランクを取得 51 distributions[rank_index][subjects_index] ++; // 任意の科目・ランクの度数を加算 52 } 53 } 54 // 出題内容の出力 55 print_data(); 56 // 以下、他の出力事例 57 // ①数学の得点を出力 58 for (students_index = 0; students_index < STUDENTS_COUNT; students_index ++) { 59 printf("%d人目の点数は%d点です", students_index, scores[students_index][MA]); 60 } 61 // ②英語の度数分布を取得 62 for (rank_index = 0; rank_index < RANK_COUNT; rank_index ++) { 63 printf("%d点以上%d点未満の人数は%d人です", rank_index * rank_step, (rank_index + 1) * rank_step, distribution[rank_index][EN]); 64 } 65}

投稿2024/03/23 15:22

編集2024/03/24 03:18
Refrain

総合スコア532

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

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

Refrain

2024/03/23 15:27

ちなみに上記のように実装しておくと、人数や科目数、ランク付け指針が変わった時に容易に対応できるメリットがあります。 元のコードですと20点刻みでif文で分岐させていましたが、`点数 / 刻み`を`int`型変数に代入して切り捨てさせ、ランクに対応したインデックスを算出しています。
0fg3873t38k3z3e

2024/03/23 15:50

ご回答ありがとうございます。質問させていただきたいと思います。数学の得点分布は、どのようにしたらよろしいでしょうか?私は…まだ初心者であり、分からないことがたくさんあります。申し訳ありませんがよろしくお願いいたします。
Refrain

2024/03/23 15:57

上記コードの要点として、英語の得点分布を`EN[6]`として定義し、ループ内では`EN[i]`を操作して分布の加算を行っています。 他の科目に対応させたい場合、`EN[6]`と同様に別の変数を定義し、ループ内で同じように加算させるだけで良いです。 コード修正しておきますね。
Refrain

2024/03/23 16:09

変数名の明確化、コメント整備によりコードが長くなりましたが対応完了しました。
Refrain

2024/03/24 03:20

設問通りの書式での出力を追加しました。
fana

2024/03/25 04:35

> 一度int型変数に代入して 「質問へのコメント」欄のところにコメントしてみていますが,何やら「実数で」という文言が質問文にあるので,ひょっとしたら int ではないかもしれません. (仮にそうだとしても特別言うほどの差は生じないでしょうが)
Refrain

2024/03/25 10:46

コード上では`int score[2][20];`の宣言がなされているので、そこは察してあげても良いのかなとは思いますね… (もし型が違っても、その程度は自己解決できるようにあってほしい限りです)
guest

0

オリジナルを基にした記述例と出力結果を下記に示します。
なお,点数データは既に回答された方が作られたデータを使わせていただきました。

また,N は正の整数になら変更しても問題ありませんが,M を変更する場合は sbj_name[M] の要素を,L を変更する場合は ctg_name[L] の要素と(区分条件に合わせて)「if (..) ... else ..」 の部分の内容を,変更する必要があります。

C

1#include <stdio.h> 2 3#define N 20 // number of students 4#define M 2 // number of subjects 5#define L 6 // number of score categories per subject 6 7int main(void) 8{ 9 char *sbj_name[M] = {"英語", "数学"}; 10 char *ctg_name[L] = {" 0 - 19", "20 - 39", "40 - 59", "60 - 79", 11 "80 - 99", "100 "}; 12 int score[M][N]; 13 int ctg[M][L]; 14 int i, j, k; 15 16 for (j = 0; j < M; j++) 17 for (k = 0; k < L; k++) 18 ctg[j][k] = 0; 19 20 for (i = 0; i < N; i++) 21 for (j = 0; j < M; j++) { 22 printf("%2d人目の%s: ", i + 1, sbj_name[j]); 23 scanf("%d", &score[j][i]); 24 if (score[j][i] < 20) 25 ctg[j][0]++; 26 else if (score[j][i] < 40) 27 ctg[j][1]++; 28 else if (score[j][i] < 60) 29 ctg[j][2]++; 30 else if (score[j][i] < 80) 31 ctg[j][3]++; 32 else if (score[j][i] < 100) 33 ctg[j][4]++; 34 else 35 ctg[j][5]++; 36 } 37 printf("\n"); 38 39 printf(" "); 40 // ******* 41 for (j = 0; j < M; j++) 42 printf(" %s", sbj_name[j]); 43 printf("\n"); 44 for (k = 0; k < L; k++) { 45 printf("%s", ctg_name[k]); 46 for (j = 0; j < M; j++) 47 printf(" %4d", ctg[j][k]); 48 printf("\n"); 49 } 50 51 return 0; 52}
1人目の英語: 0 1人目の数学: 100 2人目の英語: 10 2人目の数学: 90 3人目の英語: 20 3人目の数学: 80 (省略) 18人目の英語: 70 18人目の数学: 30 19人目の英語: 80 19人目の数学: 20 20人目の英語: 90 20人目の数学: 10 英語 数学 0 - 19 4 2 20 - 39 4 4 40 - 59 4 4 60 - 79 4 4 80 - 99 4 4 100 0 2

投稿2024/03/28 12:05

little_street

総合スコア319

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

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

0

前置き:

  • 既存の回答群が「ランク」という言葉を用いているのでこの回答もそれに倣う.
  • 質問文に「実数」という気になる語があるが,話の内容としてはどうでもいい所と思うので,この回答内のコードでは得点を int としている.

どこ/何 に困っている(というか混乱している?)のか? という原因がイマイチ判断付かないところですが……
おそらく,「ある得点がどのランクか?」というのを求める部分だけを関数にでもすると見通しが良くなるのでは無いでしょうか.

すなわち,こういうやつ:

C

1//ランクの個数 2#define N_RANK (6) //6段階 3 4//得点がどのランクに属するのかを求めて返す関数. 5//戻り値は 0-based な値.すなわち,値の範囲は [ 0, N_RANK ) である. 6int RankIndex( int Score ) 7{ 8 //どんな実装方法でも良い. 9 //とにかく引数の得点に対応した {0,1,2,..., N_RANK-1 } のいずれかの値を返す. 10}

があるとして,socre[2][20] に 2教科×20人 分のスコアが入っているのだとしたら,集計の部分は

C

1int score[2][20]; //←コレにスコアが入力されているのだとして 2 3//得点の分布を求める 4int RankHistogram[2][N_RANK] = {0}; //2教科分の度数分布 5for( int iSubject=0; iSubject<2; ++iSubject ) //2教科分のループ 6{ 7 for( int iStudent=0; iStudent<20; ++iStudent ) //20人分のループ 8 { 9 int iRank = RankIndex( score[iSubject][iStudent] ); 10 ++RankHistogram[iSubject][ iRank ]; 11 } 12}

とか混乱なく書けるのではなかろうか? と.


上記の話を関数 RankIndex の実装を適当に補って纏めると,以下のような感じ.

C

1//ランクの個数 2#define N_RANK (6) 3 4//各ランクの最低得点. 5//関数 RankIndex の実装で使用している. 6//(あと,質問文で指定されている形の出力を行う際にも何かしらこういうのが必要になると思われ) 7const int MinScoreOfRank[ N_RANK ] = { 0, 20, 40, 60, 80, 100 }; 8 9//得点がどのランクに属するのかを返す. 10//戻り値は 0-based な値.すなわち,値の範囲は [ 0, N_RANK ) である. 11int RankIndex( int Score ) 12{ 13 int iRank = 0; 14 for( /*NOP*/; iRank<N_RANK-1; ++iRank ) 15 { 16 if( Score < MinScoreOfRank[iRank+1] )break; 17 } 18 return iRank; 19} 20 21// 22int main() 23{ 24 //score[2][20] に 2教科×20人分 の得点情報を入力する処理については困っていないと思うので省略 25 int score[2][20]; 26 {//※ここではテスト用に katoy 氏の回答内のコードを借用して値を入れている 27 for( int iStudent=0; iStudent<20; ++iStudent ) 28 { 29 int p = (iStudent * 10) % 100; 30 score[0][iStudent] = p; 31 score[1][iStudent] = 100 - p; 32 } 33 } 34 35 //得点の分布を求める 36 int RankHistogram[2][N_RANK] = {0}; //全要素の初期値を0にする 37 for( int iSubject=0; iSubject<2; ++iSubject ) 38 { 39 for( int iStudent=0; iStudent<20; ++iStudent ) 40 { 41 int iRank = RankIndex( score[iSubject][iStudent] ); 42 ++RankHistogram[iSubject][ iRank ]; 43 } 44 } 45 46 //結果確認 47 //※これは質問文記載のフォーマットでの出力ではなく, 48 // RankHistogram[][] の値がどうなったか(: katoy 氏が示している結果と同じ値が得られているか否か)を確認するためのコード. 49 for( int iRank=0; iRank<N_RANK; ++iRank ) 50 { 51 printf( "%d %d\n", RankHistogram[0][iRank], RankHistogram[1][iRank] ); 52 } 53 54 return 0; 55}

投稿2024/03/25 08:22

編集2024/03/25 08:23
fana

総合スコア11663

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

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

0

コード例と実行結果例を示します。
得点の入力部は、実際の得点を設定できるようにする必要があります。コード例では一定のパターンで得点を設定しています。
a.c

c

1#include <stdio.h> 2 3const char *NAME_SUBJECTS[] = {"ENG", "MATH"}; // 科目名 4#define NUM_SUBJECTS (sizeof(NAME_SUBJECTS) / sizeof(NAME_SUBJECTS[0])) // 科目数 5#define NUM_STUDENTS 20 // 生徒数 6 7int scores[NUM_STUDENTS][NUM_SUBJECTS]; 8 9void input_points() 10{ 11 // 実装をここに追加 12} 13 14void set_inputs() 15{ 16 // deug 用の得点を設定 17 for (int s = 0; s < NUM_STUDENTS; s++) 18 { 19 int p = (s * 10) % 100; 20 scores[s][0] = p; 21 scores[s][1] = 100 - p; 22 } 23} 24 25void show_scores() 26{ 27 printf("No:\t%s\t%s\n", NAME_SUBJECTS[0], NAME_SUBJECTS[1]); 28 for (int s = 0; s < NUM_STUDENTS; s++) 29 { 30 printf("%2d:\t%3d\t%3d\n", s + 1, scores[s][0], scores[s][1]); 31 } 32} 33 34void show_ranks(int range) 35{ 36 const int num_rank = (100 / range) + 1; 37 int ranks[num_rank][NUM_SUBJECTS]; 38 // 初期化 39 for (int i = 0; i < num_rank; i++) 40 { 41 for (int j = 0; j < NUM_SUBJECTS; j++) 42 { 43 ranks[i][j] = 0; 44 } 45 } 46 47 // 集計 48 for (int s = 0; s < NUM_STUDENTS; s++) 49 { 50 for(int t = 0; t < NUM_SUBJECTS; t++) 51 { 52 ranks[scores[s][t] / range][t]++; 53 } 54 } 55 56 // 集計結果を表示 57 printf("No:\t%s\t%s\n", NAME_SUBJECTS[0], NAME_SUBJECTS[1]); 58 for (int s = 0; s < num_rank; s++) 59 { 60 char label[100]; 61 if (s < num_rank - 1) 62 { 63 sprintf(label, "%3d-%2d", range * s, range * (s + 1) - 1); 64 } 65 else 66 { 67 // 最後の範囲のラベルを設定 68 sprintf(label, "%3d ", range * s); 69 } 70 printf("%s:\t%2d\t%2d\n", label, ranks[s][0], ranks[s][1]); 71 } 72} 73int main(int argc, char **argv) 74{ 75 set_inputs(); 76 show_scores(); 77 78 printf("\n"); 79 show_ranks(20); // 20 点ごとに集計 80 return 0; // 正常終了 81}

実行例

$ ./a.out
No: ENG MATH
1: 0 100
2: 10 90
3: 20 80
4: 30 70
5: 40 60
6: 50 50
7: 60 40
8: 70 30
9: 80 20
10: 90 10
11: 0 100
12: 10 90
13: 20 80
14: 30 70
15: 40 60
16: 50 50
17: 60 40
18: 70 30
19: 80 20
20: 90 10

No: ENG MATH
0-19: 4 2
20-39: 4 4
40-59: 4 4
60-79: 4 4
80-99: 4 4
100 : 0 2

投稿2024/03/24 01:47

katoy

総合スコア22324

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問