配列について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
NKS

配列について

#1

投稿記事 by NKS » 11年前

初めまして、投稿させていただきます。
c言語の課題で配列で成績処理をするプログラムを作っています。
内容は、点数を入力していき、その合計点と平均点を出力して、
優:100~80点
良:79~70点
可:69~60
不可:60点未満
の基準で 優 良 可 不可 と判断し、それぞれの人数の合計を
出力するプログラムを作っています。
プログラムを作ってコンパイルし、実行したたところ、
優 良 可 不可 のカウントがきちんとされていません。
合計点と平均点の出力はきちんと出るのですが、
その部分だけカウントされません。
どこをどのように直したらカウントされるようになるのかを教えてください。

コード:

#include<stdio.h>

#define NUM 100

int main(void)
{
	int i,j,tmp;
	int sum = 0;
	int ten[NUM];
	int yu,ryo,ka,hu;
	
	printf("成績処理を行います。終了するときは999を入力してください。\n");
	yu = 0;
	ryo = 0;
	ka = 0;
	hu = 0;
	i=0;
	while(i<NUM){
		printf("No.%d: ",i+1);
		scanf("%d",&ten[i]);    //点数の入力
		if(ten[i] == 999){   //999が入力されると終了
			break;
		}else if(ten[i] >= 0 && ten[i] <= 100){ //0~100点以内が入力されれば合計に加算
			sum += ten[i];
			i++;
		}else{               //そうでなければもう一回入力
			printf("正しい数値を入力してください。\n");
		}
	  for(j=0;j<NUM;j++)
	  if(ten[i] < 60){      //60点未満なら不可の人数に加算
		hu++;
	  }else if(ten[i]<=69){
		ka++;        //69点以下なら可に加算
	  }else if(ten[i]<=79){    
		ryo++;       //79点以下なら良に加算
	  }else{
		yu++;        //それ以外なら優に加算
	}
	}
	
	printf("%d人の処理結果\n",i);
	printf("合計点:%d\n",sum);
	printf("平均点:%.2f\n",(double)sum/i);
	printf("「優」の数%d人\n",yu);
	printf("「良」の数%d人\n",ryo);
	printf("「可」の数%d人\n",ka);
	printf("「不可」の数%d人\n",hu);
	
	return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 配列について

#2

投稿記事 by みけCAT » 11年前

・コード中の全角スペースを全て消すか、半角スペースに置換してください。
・29行目のfor文が不要(蛇足)なので、消してください。
・25行目でi++;しているので、30~34行目の判定で正しいデータが利用できていません。
 30行目、32行目、34行目のtenを全てten[i-1]にしてください。
・コードのインデントが乱れています。適切なインデントにすることを推奨します。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NKS

Re: 配列について

#3

投稿記事 by NKS » 11年前

返信ありがとうございます。
課題ではfor文を使って処理せよとのことなのですが、for文を使用する場合、どうしたらいいでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 配列について

#4

投稿記事 by みけCAT » 11年前

NKS さんが書きました:返信ありがとうございます。
課題ではfor文を使って処理せよとのことなのですが、for文を使用する場合、どうしたらいいでしょうか?
一番単純な方法は、while(i<NUM)をfor(;i<NUM;)に書き換えることです。

真面目にやるならば、読み込んだデータをその場で加算やカウントするのではなく、
読み込みが終了してからfor文を用いて加算やカウントを行います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NKS

Re: 配列について

#5

投稿記事 by NKS » 11年前

完成しました!
ありがとうございます!!
またよろしくお願いします。

NKS

Re: 配列について

#6

投稿記事 by NKS » 11年前

すみません、なぜ30、32、34行目のtenをten[-1]にしたらできたのか解説お願いします。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 配列について

#7

投稿記事 by みけCAT » 11年前

NKS さんが書きました:すみません、なぜ30、32、34行目のtenをten[-1]にしたらできたのか解説お願いします。

まず、ten[-1]にしてもできないはずです。範囲外アクセスになります。

例えば、20行目でi=1で、10が入力されたとします。
すると、ten[1]に10が代入されます。
21行目の条件10 == 999は偽なので、次に23行目が実行されます。
23行目の条件10 >= 0 && 10 <= 100は真なので、次に24行目と25行目が実行されます。
25行目の効果で、i=2になります。ten[2]はまだ値を設定していないので、不定です。
その後30行目が実行されます。この時点でi=2であり、tenすなわちten[2]は不定です。
32行目、34行目の判定でも同様です。
ここで、30行目でtenの代わりにten[i-1]にすると、これはten[2-1]すなわちten[1]なので、
先ほど入力した10との比較が行われます。

オフトピック
この解説を書いている時、
0~100位外の点数が入力されるとカウントがおかしくなりそうであることに気がつきました。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NKS

Re: 配列について

#8

投稿記事 by NKS » 11年前

詳しくおしえていただきありがとうございます。
101と100以上の数字を入力したときカウントが加算されおかしくなりました。
そこの対策も良ければ教えていただけないでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 配列について

#9

投稿記事 by みけCAT » 11年前

NKS さんが書きました:詳しくおしえていただきありがとうございます。
101と100以上の数字を入力したときカウントが加算されおかしくなりました。
そこの対策も良ければ教えていただけないでしょうか?

コード:

printf("正しい数値を入力してください。\n");
の次の行にcontinue; (今回のループの処理を打ち切り、ループのブロックの最終行の次の処理へジャンプする)を入れてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NKS

Re: 配列について

#10

投稿記事 by NKS » 11年前

できました!
ありがとうございます、また機会があればよろしくお願いします。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 配列について

#11

投稿記事 by みけCAT » 11年前

NKS さんが書きました:できました!
ありがとうございます、また機会があればよろしくお願いします。
おめでとうございます。
完成したコードを提示していただけると助かります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NKS

Re: 配列について

#12

投稿記事 by NKS » 11年前

了解です。
こちらが完成したプログラムです。

コード:

#include<stdio.h>

#define NUM 100

int main(void)
{
	int i,tmp;
	int sum = 0;
	int ten[NUM];
	int yu,ryo,ka,hu;
	
	printf("成績処理を行います。終了するときは999を入力してください。\n");
	yu = 0;									//初期値の設定
	ryo = 0;
	ka = 0;
	hu = 0;
	i=0;
	while(i<NUM){
		printf("No.%d: ",i+1);
		scanf("%d",&ten[i]);
		if(ten[i] == 999){  //999が入力されたら終了
			break;
		}else if(ten[i] >= 0 && ten[i] <= 100){ //もし0~100点が入力されたら加算
			sum += ten[i];
			i++;       //次の人の点数
		}else{
			printf("正しい数値を入力してください。\n");
			continue; //今回のループの処理を打ち切りループのブロックの最終行の次の処理へ
		}
	  if(ten[i-1] < 60){
		hu++;		//60点未満なら不可にカウント
	
	  }else if(ten[i-1]<=69){
		ka++;		//69点以下なら可にカウント
		
	  }else if(ten[i-1]<=79){
		ryo++;		//79点以下なら良にカウント
		
	  }else{
		yu++;		//それ以上は優にカウント
	}
	}
	
	printf("%d人の処理結果\n",i);
	printf("合計点:%d\n",sum);
	printf("平均点:%.2f\n",(double)sum/i);
	printf("「優」の数%d人\n",yu);
	printf("「良」の数%d人\n",ryo);
	printf("「可」の数%d人\n",ka);
	printf("「不可」の数%d人\n",hu);
	
	return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 配列について

#13

投稿記事 by みけCAT » 11年前

ありがとうございます。
NKS さんが書きました:課題ではfor文を使って処理せよとのことなのですが
という条件があったはずですが、結局for文を使わなくても大丈夫だったのでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NKS

Re: 配列について

#14

投稿記事 by NKS » 11年前

そうでした。
for文を使ってプログラムする課題でした。
すみません、ありがとうございます。
for文を使用するといたらどこにどういう文を追加したらよろしいでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 配列について

#15

投稿記事 by みけCAT » 11年前

18行目の while(i<NUM) を for(;i<NUM;) に書き換えるだけで、for文を使ったプログラムになります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NKS

Re: 配列について

#16

投稿記事 by NKS » 11年前

すみません、書き込むの忘れてました。
データ入力はwhile文でデータ処理はfor文を使うとのことです。
要望が多くてすみません。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 配列について

#17

投稿記事 by みけCAT » 11年前

NKS さんが書きました:すみません、書き込むの忘れてました。
データ入力はwhile文でデータ処理はfor文を使うとのことです。
要望が多くてすみません。
では、まずデータが既に与えられている状態で、for文を使ったデータ処理プログラムを書くことはできますか?

コード:

#include<stdio.h>

#define NUM 100

int main(void)
{
	int i = 10,tmp;
	int sum = 0;
	int ten[NUM] = {59, 59, 59, 60, 79, 80, 100, 65, 0, 23};
	int yu,ryo,ka,hu;
	
	// ここにfor文を使って成績処理を行うプログラムを書く
	
	printf("%d人の処理結果\n",i);
	printf("合計点:%d\n",sum);
	printf("平均点:%.2f\n",(double)sum/i);
	printf("「優」の数%d人\n",yu);
	printf("「良」の数%d人\n",ryo);
	printf("「可」の数%d人\n",ka);
	printf("「不可」の数%d人\n",hu);
	
	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NKS

Re: 配列について

#18

投稿記事 by NKS » 11年前

これで正しいかはわかりませんが作ることができました。

コード:

#include<stdio.h>
 
#define NUM 100
 
int main(void)
{
    int i = 10;
    int sum = 0;
    int ten[NUM] = {59, 59, 59, 60, 79, 80, 100, 65, 0, 23};
    int yu,ryo,ka,hu;
    
	yu = 0;
	ryo = 0;
	ka = 0;
	hu = 0;
    for(i = 0;i <= 9;i++){// ここにfor文を使って成績処理を行うプログラムを書く
		if(ten[i] < 60){
			hu++;
			sum += ten[i];
		}else if(ten[i] <= 69){
			ka++;
			sum += ten[i];
		}else if(ten[i] <= 79){
			ryo++;
			sum += ten[i];
		}else{
			yu++;
			sum += ten[i];
		}
    }
    
    printf("%d人の処理結果\n",i);
    printf("合計点:%d\n",sum);
    printf("平均点:%.2f\n",(double)sum/i);
    printf("「優」の数%d人\n",yu);
    printf("「良」の数%d人\n",ryo);
    printf("「可」の数%d人\n",ka);
    printf("「不可」の数%d人\n",hu);
    
    return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 配列について

#19

投稿記事 by みけCAT » 11年前

for文の前後でiの値が変わらないようにしてください。
すなわち、for文ではiではなく別のループ変数を使用し、0から(i-1)までのループを回します。

それができたら、iの初期化をi=10からi=0に戻し、No: 12の入力処理(sum,hu,ka,ryo,yuの更新を除く)をその上に追加すればできるはずです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

NKS

Re: 配列について

#20

投稿記事 by NKS » 11年前

了解です。やってみます。
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る