C言語の配列を使ったプログラミングについて

このQ&Aのポイント
  • C言語の配列を使ったプログラミングについて
  • 5人の数学と英語の点数の合計が入る二次元配列を用意し、5人の数学と英語の合計点を計算し配列に入れるプログラムを作成する方法について解説します。
  • また、プログラム中でscanfで改行を入れない場合に発生する問題や、最低点と最高点が正しく出力されない原因についても説明します。
回答を見る
  • ベストアンサー

C言語の配列を使ったプログラミングについてです。

5人の数学と英語の点数の合計が入る二次元配列を用意し、5人の数学 (scores [i] [0]) と英語 (scores [i] [1]) の点数の入力する.5人の数学と英語の合計点を計算し配列に入れる (scores [i] [2]).数学と英語と合計の一覧を表示したあと,合計点の最高点と最低点を表示するプログラムを作れ.という問題で #include<stdio.h> int main() { char score[5][3]; int i, min=0,max=0; for(i=0; i<5; i++){ printf("%d: M E?",i+1); scanf("%d %d", &score[i][0], &score[i][1]); score[i][2]= score[i][0]+score[i][1]; if(score[max]<score[i][2]) max=i; if(score[min]>score[i][2]) min=i; } printf("id Math Eng Total\n"); for(i=0; i<5; i++){ printf("%d %d %d %d\n", i+1, score[i][0], score[i][1], score[i][2]); } printf("min: %d max: %d",score[min], score[max]); } というプログラムを作ったのですが、scanfで改行を入れていないのに、1つ目の数字を入れると2つ目の数字はなぜか改行してしまい、さらに最低点と最高点が正しく出力されませんでした。なぜでしょうか。回答よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8525/19376)
回答No.7

>ヒントには、 >char scores[5][3]; >scanf("%d %d", &scores[i][0], &scores[i][1]); >と書かれているのでcharは間違っていないと思います。 ヒント通りに作成すると「scanfを行なった時点で、メモリを破壊する」ので「ヒントそのものが間違っている」のが明白です。 世の中には「出題者そのものがバグに気付いていない」という課題が多く存在します。 出題者がバグに気付かない原因は「メモリを壊していても、この程度の例題なら、問題が表面化しない」からです。 #include<stdio.h> int main() { int score[5][3]; int i, min=0,max=0; for(i=0; i<5; i++){ printf("%d: M E?",i+1); scanf("%d %d", &score[i][0],&score[i][1]); score[i][2]= score[i][0]+score[i][1]; if(score[max][2]<score[i][2]) max=i; if(score[min][2]>score[i][2]) min=i; } printf("id Math Eng Total\n"); for(i=0; i<5; i++){ printf("%d %d %d %d\n", i+1, score[i][0], score[i][1], score[i][2]); } printf("min: %d max: %d",score[min][2], score[max][2]); return 0; } 因みに「score配列がcharの配列」だった場合、数学と英語の合計点が128点以上になると、charの値が「マイナス」になるので、確実に誤動作します。 つまり「score配列は、128以上の整数を記録出来なければならない」ので「charで定義するのは明白な誤り」です。ヒントが確実に間違っています。 因みに、以下は「charの配列のまま」で実行した結果です。 1: M E?50 50 2: M E?10 50 3: M E?100 100 4: M E?10 0 5: M E?0 10 id Math Eng Total 1 50 50 100 2 10 50 60 3 100 100 -56 4 10 0 10 5 0 10 10 min: -56 max: 100 3人目の合計が「200点」でなければならないのに「-56点」になっています。 この点からも「scoreがcharの配列であるのは明白なバグ」であり、出題者の頭がおかしいとしか思えません。

その他の回答 (6)

  • MSZ006
  • ベストアンサー率38% (390/1011)
回答No.6

#5補足です。 max,minには最高点や最低点の人が「何番目の人か」の番号(0~4)が入ります。点数そのものが入るわけではありませんのでご留意ください。 最後のprintfの中もscore[max][2]などとなります。 scanfの件は他の回答者様のおっしゃる通りです。%dを使うのであればint型の変数を使用します。int score[5][3]と宣言してください。charではダメだと思います(ヒントが間違っている?)。

  • MSZ006
  • ベストアンサー率38% (390/1011)
回答No.5

>if(score[max]<score[i][2]) >max=i; >if(score[min]>score[i][2]) >min=i; 二次元配列score[][]の中身は score[i][0] :i番目の人の数学の点数(i = 0~4) score[i][1] :i番目の人の英語の点数 score[i][2] :i番目の人の合計点 となっています。 また、scoreは2次元配列なので添え字は2個必要です。 ですからscore[max]のような添え字が1個だけ、というのは明らかに変です。 合計点の最大/最小を調べているので、if文で比較するのは、score[max][2]、score[min][2]とするのが正しいと思います。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.4

たぶんヒントが間違ってます。なぜなら、 >合計点の最高点と最低点を表示する という仕様のプログラムを書いていて、 >if(score[max]<score[i][2]) >max=i; >if(score[min]>score[i][2]) >min=i; こう書いたとき、変数iは「何人目であるか」という0~4の範囲の情報を 持っています。それに対し、 maxやminは「点数の」最高点や最低点を入れることになっています。 iとman/minは、保持する情報の属性が全く異なります。 代入するとおかしなことになります。 繰り返します。 iは「何人目」か、という情報、 man / minは「何点か」という情報をそれぞれ保持します。

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.3

> char score[5][3]; snip > scanf("%d %d", &score[i][0], &score[i][1]); snip > と書かれているのでcharは間違っていないと思います。 そのヒントとやらがおかしい。%d は int の領域が必要です。どうしても char で受けるなら %hhd とするべきでしょう。 コンパイラにもよるでしょうが、複数の警告が表示されているはずです。もし警告の抑制オプション付けてるなら外し、まずはその警告の原因を考えて、問題を修正する必要があります。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

scanfのことはいったん横へ置くとして… >if(score[max]<score[i][2]) >max=i; >if(score[min]>score[i][2]) >min=i; 別の回答者さんからの回答にもあるとおり、score[max]というのは意味不明です。 また、maxやminにiを代入していますが、正しいですか? maxやminには「score」が入るのではないのですか?iという添字じゃなくって。

kasu9695
質問者

補足

ヒントに char scores[5][3]; int i,min=0,max=0; for(i=0; i<5; i++) { scanf("%d %d", &scores[i][0], &scores[i][1]); // scores[i][2]の計算をする // scores[i][2]の最低点か? 最低点ならmin=iをする // scores[i][2]の最高点か? 最高点ならmax=iをする } for(i=0; i<5; i++) { // 表示 } と書かれているのでmin=iやmax=iは間違えていないと思います。score[max]は過去の問題を参考にしたものなので私自身よくわかっていません。すみません。

  • f272
  • ベストアンサー率46% (8021/17144)
回答No.1

char score[5][3]; となっているが,どうしてcharなのですか?点数を入れるのではないですか? if(score[max]<score[i][2]) となっているが,どうしてscore[max]とscore[i][2]を比較するのですか?このときscore[max]には何が入っていると考えているのですか?

kasu9695
質問者

補足

ヒントには、 char scores[5][3]; int i,min=0,max=0; for(i=0; i<5; i++) { scanf("%d %d", &scores[i][0], &scores[i][1]); // scores[i][2]の計算をする // scores[i][2]の最低点か? 最低点ならmin=iをする // scores[i][2]の最高点か? 最高点ならmax=iをする } for(i=0; i<5; i++) { // 表示 } と書かれているのでcharは間違っていないと思います。score[max]は過去の問題を参考に入れたものであり私自身よく分かっていません。すみません。

関連するQ&A

  • プログラミング(C言語)についての質問です

    3つの整数の入力を受け付け、最大と最小を求める関数を作成し得られた結果を表示するプログラミングを作成したつもりなのですが、うまく作動しません。(コンパイルはできますが、結果が無茶苦茶になります。) ご教授宜しくお願いします。 それと、課題文にはポインタを使って最大値と最小値を同時に求めるようにと書いてあったのですが、それもよくわからないです。 今回初めてポインタと配列の受け渡しについて習ったのでよくわかっていない部分も多いと思うのですが、何卒宜しくお願いします。 ちなみに関数の形自体は void minmax(int data[],int *min,int *max){} で決まっています。 #include <stdio.h> void minmax(int data[],int *min,int *max){ int i; *min=*max=data[0]; printf("1st intenger:"); scanf("%d",&data[0]); printf("2st intenger:"); scanf("%d",&data[1]); printf("3st intenger:"); scanf("%d",&data[2]); for(i=1;i<3;i++){ if(*max<data[i]){ *max=data[i]; } if(*min>data[i]){ *min=data[i]; } } } int main(void){ int data[3],min,max; minmax(data,&min,&max); printf("最小値は%dで最大値は%dです",min,max); return 0; }

  • C言語の配列について

    配列を20 定義し値を入力して合計値を出したいのですがどうすればよいのでしょうか 下のソースでエラーはおこりませんでした 何がちがうのでしょうか #include <stdio.h> int main() { int a[20]={}; int i, sum; printf("整数を入力してください:"); scanf("%d",&a); printf("\n"); for (i = 0; i < 10; i++) { sum += a[i]; } printf("sum= %d\n", sum); return 0; }

  • C言語 プログラミング 行列演算

    下記のプログラムのおかしい点と解決法を教えてください。 コンパイルは通りますがうまく動きません。。 #include<stdio.h> #define MAX 500 int main(void){ int matrA[MAX][MAX],matrB[MAX][MAX],matrC[MAX][MAX],l,m,n,i,j,k; printf("lとmを入力してください:"); scanf("%d",&l); scanf("%d",&m); printf("行列Aを入力してください"); for(i=0;i<l;i++){ printf(">"); for(j=0;l<m;j++){ scanf("%d",&matrA[i][j]); } printf("\n"); } printf("nを入力してください(m = %d):",m); scanf("%d",&n); printf("行列Bを入力してください"); for(i=0;i<m;i++){ printf(">"); for(j=0;j<n;j++){ scanf("%d",&matrB[i][j]); } printf("\n"); } printf("C=\n"); for(i=0;i<l;i++){ for(j=0;j<n;j++){ for(k=0;k<m;k++){ matrC[i][j]+=matrA[i][k]*matrB[k][j]; } printf("%d",matrC[i][j]); } printf("\n"); } }

  • プログラミング・C言語の配列(単純選択ソート)についてです

    最近プログラミングを勉強し始めた初心者です。 今、配列について勉強していて あるプログラムを作成しています。 それは10個の実数を入力して、入力された実数を降順に並び替えるものなのですが、 降順に並び替えることができません(泣 どこが違うのか教えていただきたいのですが・・・ よろしくお願いします。 #include <stdio.h> #define NUMBER 10 int main(void) { int i, j, min, min_a, temp; double zissu[NUMBER]; printf("%d個の実数を入力してください", NUMBER); min=i; printf("date[%d]:", i); scanf("%lf", &zissu[i]); for(j=i+1; j<NUMBER; j++) { if(zissu[j] < zissu[min]) min_a =j; } temp = zissu[min]; zissu[min] = zissu[min_a]; zissu[min_a] = temp; } for(i = 0; i < NUMBER; i++) printf("date[%d]=%lf \n", i, zissu[i]); return (0); } 【入出力例】 10個の実数を入力してください data[0]:24.2 data[1]:2 ・・・ data[9]:9 降順にソートしました data[0] = 2 data[1] = 9 data[2] = 24.2 ・・・ みたいにしたいのです。 よろしくお願いします

  • n人の教科ごとの最高点、最低点を求めるプログラム

    n人の教科ごとの最高点、最低点を求めるプログラム C言語で、タイトルのようなプログラムを作成しています。(n≦100) 教科は国語、数学、英語の3教科です。 作る際の条件として、最高点と最低点を同時に求める関数minmaxを一つだけしか作れません。 入力例) % ./a.out number of persons: 3 Japanese Math English No.1: 90 80 70 No.2: 71 91 81 No.3: 82 72 92 min score: 71 72 70 max score: 90 91 92 現在、構造まで習いました。その知識をもとに以下のようにプログラムしました。(ただ、教科ごとの最高、最低点を求める部分は代表して国語の点の最低点を求める部分だけ載せました) #include <stdio.h> #define MAX 100 struct score{     int jpn;     int math;     int eng; }; void minmax(struct score, int, struct score *, struct score *); main(){     struct score s[MAX], min, max;     int n, i;     printf("number of persons: ");     scanf("%d", &n);     printf("Japanese, Math, English\n");     for (i = 0; i < n; i++) {         printf("No.%d: ", i+1);         scanf("%d %d %d", &(s[i].jpn), &(s[i].math), &(s[i].eng));     }     minmax(s[MAX], n, &min, &max); <------------(☆)     printf("min score: %3d%3d%3d\n", min.jpn, min.math, min.eng);     printf("max score: %3d%3d%3d\n", max.jpn, max.math, max.eng); } void minmax(struct score s[], int n, struct score *minscore, struct score *maxscore) {     int i, max, min;     for (i = 1, min = s[0].jpn; i < n; i++) {         if (min > s[i].jpn) {             min = s[i].jpn;         }     }     minscore->jpn = min; (以下略) } しかし、これをコンパイルすると、 「(☆):パラメータの型1が関数宣言と一致しません。」と出ます。 どこがおかしいのでしょうか、どなたか教えてください。

  • C言語プログラミングで・・・

    つい最近、C言語プログラミングのお勉強をはじめた中学生です。 ある程度かけるようになってきて、こちらのサイトに掲載されている練習問題を解いていました。 http://akabas.net/lib/CExercise.aspx いろいろといていく中で、配列の章にはいりました。 配列の章の中の6問目と7問目の九九についてのコードを書いていたところ、どちらも問題なく実行を終了した後 「○○.exeは動作を停止しました。」というメッセージが現れました。 これはコードに何か問題があるのでしょうか? _____________________________________________________________________ //6問目 #include <stdio.h> void line (void){ int cnt; for (cnt = 0; cnt < 30; cnt++) printf("_"); printf("\n"); } int main() { int kuku[9][9], i, j; printf("九九を表示します\n"); for (i = 1; i <= 9; i++){ for (j = 1; j <= 9; j++){ kuku[i][j] = i * j; printf("%d * %d = %d\n", i, j, kuku[i][j]); } line(); } return 0; } ____________________________________________________________________ //7問目 #include <stdio.h> int main() { int kuku[9][9]; int i, j; for (i = 1; i <= 9; i++){ for (j = 1; j <= 9; j++) kuku[i][j] = i * j; } printf("1桁の数値(1 ~ 9に限定)を入力してください 1回目---"); scanf("%d", &i); printf("1桁の数値(1 ~ 9に限定)を入力してください 2回目---"); scanf("%d", &j); printf("\n"); printf("%d * %d = %d", i, j, kuku[i][j]); return 0; } ________________________________________________________________________________ まだ初心者のレベルなので、回答はできたらきつい言葉をつかってほしくないです^^; よろしくおねがいします ※こちらでは、Tabをうっているのですが、表示されてないみたいです。見づらいかと思いますが、よろしくおねがいします

  • C++のscanfについて

    今C++をやり始めたばかりの者です 下記のように打って、コンパイルして実行すると、数字はちゃんと出るんですが英語は入るとループがかかってしまいます。 英語のループを回避して、平均が出るように出来ないでしょうか。。。。 返答よろしくお願いします。。。。。 /********************************************** 平均を求める ***********************************************/ #include <stdio.h> #define END -1 //-1が入力されたら終わり void main() { //変数の宣言 int score; //得点 int total; //合計 double ave; //平均点 int i; //回数のカウント //入力と合計の計算 total = 0; //初期設定 i = 0; //最初の得点を入力 printf("%d科目めの得点を入力 : ", i+1); scanf("%d" , &score); //入力 while( score > END ) { total += score; i++; printf("%d科目目の得点を入力 : ", i+1); scanf("%d" , &score); //次を入力 } ave = (double)total / i; //平均を求める //表示 printf("合計:%5d点 平均:%7.1lf点\n" , total , ave); }

  • C言語のプログラムでおかしな動作をするのですが教えて頂けないでしょうか?

    VisualStudio2008使用しています。 問題は、サイコロを200回振ってその出た目の数の個数分*を表示するプログラムです。 サイコロの目はランダムで出しています。 次のプログラムは正常に動作するものです。 /* #include <stdio.h> #include<stdlib.h> #include<time.h> #define N 200 int DICE(int min,int max); int main() { int n,i,j; int y[7]={0}; srand((unsigned int)time(NULL)); for(i=0;i<N;i++){ n=DICE(1,6); y[n]++; } for(i=1;i<7;i++){ printf(" %2d: ",i); for(j=0;j<y[i];j++){ printf("*"); } printf("\n"); } return 0; } int DICE(int min,int max) { return min+(int)(rand()*(max-min+1.0)/(1.0+RAND_MAX)); } */ 次のプログラムが問題で、授業で先生が配列にはstaticをおまじないとしてつけないと暴走すると言われたので、つけて見ると明らかに間違ってると思われるプログラムで動作するのですが原因を教えて頂けないでしょうか? 以下問題のプログラム! 配列の前にstaticをつけたら、添え字をいくつにしても正常に動作します。普通は添え自分しか領域って確保されないですよね??? /* #include <stdio.h> #include<stdlib.h> #include<time.h> #define N 200 int DICE(int min,int max); int main() { int n,i,j; //以下が問題の配列宣言 static int y[2]={0}; srand((unsigned int)time(NULL)); for(i=0;i<N;i++){ n=DICE(1,6); y[n]++; } for(i=1;i<7;i++){ printf(" %2d: ",i); for(j=0;j<y[i];j++){ printf("*"); } printf("\n"); } return 0; } int DICE(int min,int max) { return min+(int)(rand()*(max-min+1.0)/(1.0+RAND_MAX)); } 質問の意味が正確に伝わらなかった場合は補足しますので、ご回答よろしくお願いします。

  • C言語 最大値と最小値を求めて表示するプログラム

    はじめまして。 C言語を学習中です。 下記の問題演習の解答として記載されているプログラムがどうしても理解できません。 特にプログラムの最後の方のwhile文で最大値と最小値の判定をしているのかと思いますが、どのような計算をして判定しているのでしょうか。 while (array[i] != -1) { if (array[i] > *max) *max = array[i]; if (array[i] < *min) *min = array[i]; i++; 具体的に教えてください。 よろしくお願い致します。 ●問題 0~100の範囲で入力された複数の数値の中から、 最大値と最小値を求めて表示するプログラムを作成せよ。 -1が入力された場合は入力の終わりと判定する。 ただし、最大値と最小値はmain関数以外の一つの関数の中で求める。 また、入力された数値を記憶する配列の要素数は10とし、 それ以上入力された場合はエラーが起きても仕方ないこととする。 ヒント:配列の中に -1 があればデータの終わりだと判断できる。 ヒント:最小値を探すには、最大値を記憶した変数との比較を繰り返せば良い。 ●解答 #include <stdio.h> void maxmin(int array[],int *max,int *min); int main(void) { int i = 0,array[10],max,min; do { printf("%d 番目の数:",i + 1); scanf("%d",&array[i]); i++; } while (array[i - 1] != -1); maxmin(array,&max,&min); printf("最大値 %d : 最小値 %d\n",max,min); return 0; } void maxmin(int array[],int *max,int *min) { int i = 0; *max = 0; *min = 100; while (array[i] != -1) { if (array[i] > *max) *max = array[i]; if (array[i] < *min) *min = array[i]; i++; } }

  • C言語で3次元配列の課題をしています。

    C言語で3次元配列の課題をしています。 5人の学生の3科目(国数英)の点数を前期と後期の2回分について三次元配列に入力し、各学生の前期と後期の合計と前・後期の合計を求めるプログラムです。 配列に数値を格納するあたりまでは分かったものの、そこから先がよくわからなくなってしまいました。どなたか解説とともに、成績の出力の仕方を教えていただけないでしょうか。for文を使えばいいというのはわかりますが・・・。 以下に出来た部分までのソースを載せておきます。まだ未熟な上、変なミスがあるかもしれません。 #include <stdio.h> main() { /*配列を宣言*/ int score[0][3][5],i,j,k; int total,sum[2][5]; /*配列に成績を入力*/ for(i=0;i<2;i++){ for(j=0;j<3;j++){ for(k=0;k<5;k++){ printf("score[%d][%d][%d] = ",i,j,k); scanf("%d", &score[i][j][k]); } } } /*合計を計算する*/ for(i=0;i<5;i++){ for(j=0;j<2;j++){ total=0; for(k=0;k<3;k++){ total = total + score[i][j][k]; } sum[i][k]=total; } sum[2][k]=sum[0][k]+sum[1][k]; } /*出力する*/ /*??*/ } ※三次元配列のscoreの始めの[]は、0が前期成績、1が後期成績を格納する部分です。