![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
平均値を関数を用いて出力したいのですが一箇所でつまずいてしまい
ました。ソースは
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/*構造体宣言*/
struct Students{
int N;
int A;
int B;
int C;
double ave;
};
/*平均値を計算する関数*/
struct Students Average(struct Students std[i]){
std[i].ave=(double)(std[i].A+std[i].B+std[i].C)/3;
return std[i];
}
int main(void){
struct Students std[49]; /*構造型配列*/
int i,N,A,B,C,num,scannum;
FILE*file; /*ファイルのポインタを用意*/
srand((unsigned)time(NULL)); /*乱数の初期化/
file=fopen("Data.txt","r"); /*Dataファイルの読み込み*/
/*ファイルのオープンチェック*/
if(file==NULL){
fprintf(stderr,"cannnot open file 'Data.txt'\n");
exit(1);
}
/*Studentsにデータを格納*/
for(i=0;i<=49;i++){
fscanf(file,"%d%d%d",&N,&A,&B);
std[i].N=N;
std[i].A=A;
std[i].B=B;
std[i].C=70+(rand()/(RAND_MAX+1.0)*31);
std[i].ave=Average(std[i]);
/*表示*/
printf("学籍番号:%d.",std[i].N);
printf("科目A:%d.\n",std[i].A);
printf("科目B:%d.\n",std[i].B);
printf("科目C:%d.\n",std[i].C);
printf("平均点:%d.\n",std[i].ave);
fclose(file);
return 0;
}
目標はA,B,Cの平均を出したいのですが関数宣言の際にstd[i]を
用いると未定義扱いになってしまい実行が出来ない状態です。
自分としては↑のソースでi番目の配列の平均値を導出し、表示
させようとしてるのですが。。。。アドバイスをお願いします。
m(__)m
No.3ベストアンサー
- 回答日時:
double Average(struct Students tmp);
{
return (double)(tmp.A+tmp.B+tmp.C)/3;
}
のようにするべきでは?
関数を呼び出すときの引数は値をコピーするための一時的な変数です。
std[i].ave = Average(std[i]);
としてAverage関数を呼び出すときには
struct Students Average(struct Students tmp)
tmp = std[i];
{
return (double)(tmp.A+tmp.B+tmp.C)/3;
}
とちょっと書き方は変になりますが、std[i]という変数を一時的に引数で宣言されている変数にコピーして
関数の中で計算を行いますので、std[i]のように名前が同じである必要がありません。
名前を同じにしても良いのですが、関数の中と外とでは全く違う変数として扱われます。
また、引数として宣言できる変数名は普通の変数宣言と同じ形式ですので
std[i]というような変数名を宣言することはできません。
あと、averageの中身ですが平均値を計算したいのであれば上記のように
平均値を戻り値としないと
std[i].ave=Average(std[i]);
で、型が違うのでエラーがでるのでは?
この回答への補足
アドバイスありがとうございます。参考にさせて頂いたのですが
自信がありません。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/*構造体宣言*/
struct Students{
int N;
int A;
int B;
int C;
double ave;
};
/*平均値を計算する関数*/
struct Students Average(struct Students tmp){/*←構造体tmpを引数とする平均関数*/
tmp=std[i]; /*平均関数の式。構造体tmpに構造体std[i]の値を代入*/
tmp.ave=(double)(tmp.A+tmp.B+tmp.C)/3; /*平均関数の式2.↑から得た平均値を求める*/
return(double)tmp.ave; /*戻り値は平均値*/
}
int main(void){
struct Students std[50]; /*構造型配列*/
int i,N,A,B,C,num,scannum;
FILE*file; /*ファイルのポインタを用意*/
srand((unsigned)time(NULL)); /*乱数の初期化*/
file=fopen("Data.txt","r"); /*Dataファイルの読み込み*/
/*ファイルのオープンチェック*/
if(file==NULL){
fprintf(stderr,"cannnot open file 'Data.txt'\n");
exit(1);
}
/*Studentsにデータを格納*/
for(i=0;i<=49;i++){
fscanf(file,"%d%d%d",&N,&A,&B);
std[i].N=N;
std[i].A=A;
std[i].B=B;
std[i].C=70+(rand()/(RAND_MAX+1.0)*31);
std[i].ave=Average(tmp);
/*表示*/
printf("学籍番号:%d.",std[i].N);
printf("科目A:%d.\n",std[i].A);
printf("科目B:%d.\n",std[i].B);
printf("科目C:%d.\n",std[i].C);
printf("平均点:%f.\n",std[i].C);
fclose(file);
return 0;
}
アドバイスを頂いた関数の部分に自分なりの解釈をメモしたのですが
これで正しいでしょうか?このソースでコンパイルするとエラーが
出てきてしまいました。
1>c:\documents and settings\devil\my documents\visual studio 2008\projects\レポート\レポート\test1.c(16) : error C2065: 'i' : 定義されていない識別子です。
1>c:\documents and settings\devil\my documents\visual studio 2008\projects\レポート\レポート\test1.c(16) : error C2109: 配列または、ポインタでない変数に添字が使われました。
1>c:\documents and settings\devil\my documents\visual studio 2008\projects\レポート\レポート\test1.c(18) : error C2440: 'return' : 'double' から 'Students' に変換できません。
1>c:\documents and settings\devil\my documents\visual studio 2008\projects\レポート\レポート\test1.c(44) : warning C4244: '=' : 'double' から 'int' への変換です。データが失われる可能性があります。
1>c:\documents and settings\devil\my documents\visual studio 2008\projects\レポート\レポート\test1.c(45) : error C2065: 'tmp' : 定義されていない識別子です。
1>c:\documents and settings\devil\my documents\visual studio 2008\projects\レポート\レポート\test1.c(45) : error C2440: '関数' : 'int' から 'Students' に変換できません。
1>c:\documents and settings\devil\my documents\visual studio 2008\projects\レポート\レポート\test1.c(45) : warning C4024: 'Average' : の型が 1 の仮引数および実引数と異なります。
1>c:\documents and settings\devil\my documents\visual studio 2008\projects\レポート\レポート\test1.c(45) : error C2440: '=' : 'Students' から 'double' に変換できません。
1>c:\documents and settings\devil\my documents\visual studio 2008\projects\レポート\レポート\test1.c(58) : fatal error C1075: 左側 中かっこ '{' に対応するものが 'c:\documents and settings\devil\my documents\visual studio 2008\projects\レポート\レポート\test1.c(21)' で見つかる前に EOF が検出されました。
以前に他の方のアドバイスも参考にさせていただきだいぶエラーが減
ったのですが未だに。。。。
大変参考になりました。当初はこのアドバイスでもいまいち理解に
かけていましたが引数と仮引数、左と右の型に注目することで
実行することが出来ました。ありがとうございました。
No.8
- 回答日時:
#4です。
>[49]とすると0から49までの合計50個になる気がするんですが
[49]とすると49個欲しいって宣言で、使えるのは[0]から[48]までです。
int n[0];って宣言はコンパイルできないでしょ。
ついでに言うと
for(i=0;i<=49;i++){ より
for(i=0;i<50;i++){ のほうが一般的だと思います。
ANo.3の頭の部分を重視して欲しかった。
(よく見るとセミコロンが余分でしたが)
それと(double)の位置が変みたい。は取り下げます。
/3が気になったのだけど、ちゃんと動くようなので。
あと、Data.txtは150行あると思っていいのかな?
うまく動かなかったらData.txtの最初の3行ぐらいを教えてください。
配列を復習したところ明らかに私のミスでした。すいません。。。
当初ANo3さんのアドバイスでさえ理解に苦しみましたが
Averageの仮引数と中身を整理した結果、ANo3さんに書いていただいた
ソースになりました。
>あと、Data.txtは150行あると思っていいのかな?
はい、150行でした。実行結果にもしっかりと出ました。
アドバイスありがとうございました。
No.7
- 回答日時:
とりあえず、関数と引数、変数のスコープについて整理しましょう。
スコープという単語がわからないようでしたら、もう一度教科書なり参考書なりで、関数について学んでください。
この部分は基本的なことですので、お持ちのそれらをご覧になったほうが早いかもしれません。
また、No.3での回答の途中にある文章は説明するための文章であって、プログラムじゃありません。さらにソース部分、説明部分ともに、関数の戻り値定義がおかしいままです。
関数定義を以下のとおりに変更してください。
double Average(struct Students tmp)
{
return (double)(tmp.A+tmp.B+tmp.C)/3;
}
呼び出しは今までどおり、
std[i].ave = Average(std[i]);
です。
あと、fcloseの前に}が必要と思われます。
これらでとりあえず動くはずです。動いたら、動かなかったときとなにが違うのかを確認してください。また、なぜこれで動くのかを確認してください。
回答ありがとうございます。動かなかった原因としては
仮引数であるtmpをmain関数内で変数として使ったいたこと。
for文の括弧が欠落
tmp.aveに反映してたつもりだったこと
だと考えております。
この後偏差値を求めるソースを追加しなくてはならないので
実践としてやってみたいと思います。
回答ありがとうございました。
No.6
- 回答日時:
平均を求める関数を
/*平均値を計算する関数*/
double Average(struct Students tmp){
return (double)(tmp.A + tmp.B + tmp.C)/3.0;
}
といった具合に
50人分なら
struct Students std[50]; /*構造型配列*/
とします
結果の表示で
printf("平均点:%d.\n",std[i].ave);
を
printf("平均点:%lf\n",std[i].ave);
としましょう
No.5
- 回答日時:
> [49]とすると0から49までの合計50個になる気がするんですが
49は要素数。
> 私の思い違いでしょうか?
そうです。
参考書なりを調べたらすぐ分かると思います。
http://homepage3.nifty.com/mmgames/c_guide/13-01 …
> これで正しいでしょうか?
> このソースでコンパイルするとエラーが出てきてしまいました。
エラーが出てるなら正しくないのでは?
エラーメッセージをみればどこが間違ってるか何を間違ってるか分かるんだから、
せめてエラーを全部無くしてください。
> tmp=std[i]; /*平均関数の式。構造体tmpに構造体std[i]の値を代入*/
意味不明。なんで関数Average内にこんな記述があるの?
> tmp.ave=(double)(tmp.A+tmp.B+tmp.C)/3; /*平均関数の式2.↑から得た平均値を求める*/
tmp.aveに代入してもそれが呼び出し元には反映されないのは分かってる?
> return(double)tmp.ave; /*戻り値は平均値*/
関数Averageの戻り値はstruct Students型と宣言してるのに
ここではdouble型になってる。
> std[i].ave=Average(tmp);
tmpなんて変数は存在しない。
右辺がstruct Students型なのに左辺がdouble型。
>意味不明。なんで関数Average内にこんな記述があるの?
根本的に仮引数の思い違いをしていました。。。
>tmp.aveに代入してもそれが呼び出し元には反映されないのは分かってる?
当初は反映されてると思っていました。
>tmpなんて変数は存在しない。
右辺がstruct Students型なのに左辺がdouble型。
引数と仮引数を混同しておりました。ここのアドバイスのおかげで
無事エラーをなくして実行できるようになりました。
アドバイスありがとうございました。
No.1
- 回答日時:
ちゃんと見てないけど
std[i].ave=Average(std[i]);
なら
double Average(struct Students std[i]){
じゃない?
閉じる括弧も足りないようだし
実行できない以前にコンパイルできないでは?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# C++初心者です stirng 2 2022/09/20 20:43
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# メインプログラムに#include <algorithm>を書いて、 そのメインプログラムが // 3 2023/05/02 11:24
- C言語・C++・C# このプログラミング誰か教えてくれませんか 3 2022/05/13 17:27
- C言語・C++・C# このプログラミング誰か教えてくれませんか 2 2022/05/14 09:45
- C言語・C++・C# このプログラミングの問題を教えてほしいです。 キーボードからデータ数nとn個のデータを入力し、平均値 3 2022/12/19 22:51
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
#define中の#のエスケープ
-
C++で、テキストファイルを一行...
-
enumの値から定義名を文字列化...
-
wstringの主力
-
switch文のエラーについて
-
2次元vectorのerase?
-
C言語のポインターで詰まっている
-
VS2019でofstreamが未定義になる
-
構文エラーが出ているのですが...
-
string型のフォーマット書式指...
-
VC++で文字列から任意の文字を...
-
構造体配列のvectorへの変換と...
-
findnext();について
-
C++でのeの近似値の求め方
-
プログラミング言語Cとプログラ...
-
CStringとString
-
ヘッダーファイルがインクルー...
-
指定した文字を削除したい
-
#include "fstream.h"
-
boost::regexで、日本語に利用...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構文エラーが出ているのですが...
-
switch文のエラーについて
-
enumの値から定義名を文字列化...
-
VC++で文字列から任意の文字を...
-
なぜ、C++の標準ヘッダをインク...
-
空ENTERの判別
-
std::wstringのメモリリークに...
-
C言語からgnuplot呼び出し
-
リモートデスクトップの接続元I...
-
JPEGやPNGが読めるLoadImage関数
-
このプログラミング誰か教えて...
-
プログラミング
-
#include "fstream.h"
-
C++での <iostream.h>と<iostre...
-
std::map の const 修飾について
-
構造体配列のvectorへの変換と...
-
#defineの使い方について
-
VS2019でofstreamが未定義になる
-
指定した文字を削除したい
-
構造体に決められた文字列を入...
おすすめ情報