• ベストアンサー

C言語 構造体でつまずいています

以下、番号と点数を入力して構造体配列に入力し、番号に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); //平均値を戻り値として返す }

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

  • ベストアンサー
  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

countが0かどうかを判定すれば良いでしょう if (count > 0) { printf("\n**以上%d名の平均点:%0.1f点**\n",count,heikin(score)); } とか heikin( )関数内でcountをチェックするとか

yoro4423
質問者

お礼

ありがとうございました。 言われると納得できるんですが、まだ私も初心者です。

その他の回答 (2)

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.3

>まだ私も初心者です。  ・これだけ書ければ、「初心者」ではないと・・。 ★総じて、「判り易い」ソースと思いました。 ------------------------------------------------ ☆暇な年寄りが、僭越にもちょっと添削させて頂きました。  ・「骨組み」はそのままで、◆は、やや(?)変更。  ・後は、同じ「学生番号」が入れられた時の処理?     → 構造体を「ポインタ」で扱うより、「配列の添え字」での   方が簡単そう。      例)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 ); // 平均値を戻り値として返す } 注:インデントに全角空白を用いています。   タブに一括変換して下さい。

noname#29459
noname#29459
回答No.2

はっきりいって、相当にダメなプログラムですね。 アマチュアの手習いだと思って、指導します。 ダメなところ。 a)nyuryoku を抜けた状態での状態管理が出来ていない。  しいていえば、countがそうなのであろうが、これが、グローバル変数である必要はない。nyuryokuでの状態管理として、もっとも大事なのは、有効なレコードが、何件いれられたかであるから、それを、返り値としてかえす。 b)学生番号入力ゼロは、入力終了の入力なので、breakではなく、終了処理を書いて、returnする。 c)mainで、nyuryokuの返り値を、処理して、構造体トップアドレスと有効データ数を、heikinに渡すようにする。そして、heikinでは、有効データ数のチェックなどの論理は含まない。 もちろん、ゼロ除算は、今は、count==0で、nyuryokuを抜けているから。

関連するQ&A