プロが教えるわが家の防犯対策術!

以下、番号と点数を入力して構造体配列に入力し、番号に0が入力されたら、入力処理をやめ、平均点を表示するプログラムです。
 今のコードでは、最初から番号に0を入力すると、0除算になりエラーになります。どうすれば良いのでしょうか?

#include <stdio.h>
#define MAX 50//配列の要素数を定義

int count=0;//グローバル変数

struct data {//構造体の定義
int num;//メンバの宣言
int ten;
};

void nyuryoku(struct data *);//プロトタイプ宣言
float heikin(struct data *);//プロトタイプ宣言

void main()
{
struct data score[MAX];//構造体の宣言

printf("**学生番号/点数入力**\n");
printf("\n");

nyuryoku(score);//nyuryoku関数呼び出し

printf("\n**以上%d名の平均点:%0.1f点**\n",count,heikin(score));
//heikin関数の戻り値表示

}

//nyuryoku関数
//機能:構造体配列にデータを入力する
void nyuryoku(struct data *pd)//仮引数pdに構造体ポインタが渡る
{
int i;

for(i=0;i<MAX;i++){
printf("学生番号>>");
scanf("%d",&pd->num);

if(pd->num==0){//学生番号に0を入力するとループを抜ける
break;
}

printf("点  数>>");
scanf("%d",&pd->ten);

count++;//人数のカウント

pd++;//構造体配列を一つずらす
}
}

//heikin関数
//機能:構造体配列の点数の平均を計算、戻り値として返す
float heikin(struct data *pd)//仮引数pdに構造体ポインタが渡る
{
int i;
int sum=0;
float ave=0;

for(i=0;i<MAX;i++){
if(pd->num==0){
break;
}
else{
sum+=pd->ten;//点数を加算

pd++;
}
}

ave=(float)sum/count;//平均値を求める

return(ave);//平均値を戻り値として返す
}

A 回答 (3件)

countが0かどうかを判定すれば良いでしょう


if (count > 0) {
printf("\n**以上%d名の平均点:%0.1f点**\n",count,heikin(score));
}
とか
heikin( )関数内でcountをチェックするとか
    • good
    • 0
この回答へのお礼

ありがとうございました。

言われると納得できるんですが、まだ私も初心者です。

お礼日時:2008/05/02 11:55

>まだ私も初心者です。



 ・これだけ書ければ、「初心者」ではないと・・。

★総じて、「判り易い」ソースと思いました。
------------------------------------------------
☆暇な年寄りが、僭越にもちょっと添削させて頂きました。

 ・「骨組み」はそのままで、◆は、やや(?)変更。

 ・後は、同じ「学生番号」が入れられた時の処理?
 
  → 構造体を「ポインタ」で扱うより、「配列の添え字」での
  方が簡単そう。
     例)sScore[ i ].iTen

#include <stdio.h>

#define MAX 50 // 配列の要素数を定義

int igCount = 0; // グローバル変数

typedef struct{ // 構造体の定義
 int iNum; // メンバの宣言
 int iTen;
}DATA;

void Nyuryoku( DATA * ); // プロトタイプ宣言
float Heikin( DATA * ); // プロトタイプ宣言

void main()
{
 DATA sScore[MAX]; // 構造体の宣言

 printf( "**学生番号/点数入力**\n\n" );

 Nyuryoku( sScore ); // Nyuryoku関数呼び出し

// Heikin関数の戻り値表示
 printf( "\n**以上 %d 名の平均点:%0.1f点**\n", igCount, Heikin( sScore ) );
}
void Nyuryoku( DATA *pScore )
// 機能:構造体配列にデータを入力する
// 仮引数pScoreに構造体ポインタが渡る
{
 int i;

 for( i = 0; i < MAX; i++ ){

  printf( "学生番号(0:終了)>>" );

  scanf( "%d", &pScore->iNum );

  if( 0 == pScore->iNum ) break; // 学生番号に0を入力するとループを抜ける

  printf( "点  数>>" );

  scanf( "%d", &pScore->iTen );

  igCount++; // 人数のカウント

  pScore++; // 構造体配列を一つずらす
 }
}
float Heikin( DATA *pScore )
// 機能:構造体配列の点数の平均を計算、戻り値として返す
// 仮引数pScoreに構造体ポインタが渡る
{
 int i;
 int iSum = 0;
 float dAve; // 初期化不要

 if( 0 == igCount ) return( -99.9 ); // ◆ご質問主旨

 for( i = 0; i < igCount; i++ ){ // ◆ MAX → igCount

  iSum += pScore->iTen; // 点数を加算

  pScore++;
 }
 dAve = (float)iSum / (float)igCount; // 平均値を求める

 return( dAve ); // 平均値を戻り値として返す
}
注:インデントに全角空白を用いています。
  タブに一括変換して下さい。
    • good
    • 0

はっきりいって、相当にダメなプログラムですね。


アマチュアの手習いだと思って、指導します。

ダメなところ。

a)nyuryoku を抜けた状態での状態管理が出来ていない。
 しいていえば、countがそうなのであろうが、これが、グローバル変数である必要はない。nyuryokuでの状態管理として、もっとも大事なのは、有効なレコードが、何件いれられたかであるから、それを、返り値としてかえす。

b)学生番号入力ゼロは、入力終了の入力なので、breakではなく、終了処理を書いて、returnする。

c)mainで、nyuryokuの返り値を、処理して、構造体トップアドレスと有効データ数を、heikinに渡すようにする。そして、heikinでは、有効データ数のチェックなどの論理は含まない。

もちろん、ゼロ除算は、今は、count==0で、nyuryokuを抜けているから。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています