構造体
構造体
またまたやってきました。
構造体ついての質問です。。
「学生の名前と国語、英語、数学の3科目の点数、合計点を保存するためのデータ構造を設計しなさい型名は StdData とすること。また、キーボードから人数と、人数分のそれらのデータを StdData 型の配列に格納し、配列の要素のデータを順に出力するプログラムを作成しなさい。」
こんな問題です。
こんな実行結果になります。
「
The number of students: 7
1: kim 82 57 74
2: otsuki 78 92 65
3: atsumi 88 64 83
4: hachisu 63 74 69
5: miyazawa 76 57 79
6: yokomori 95 89 81
7: nakamiti 73 64 92
name | jpn eng math| sum
kim | 82 57 74 | 213
otsuki | 78 92 65 | 235
atsumi | 88 64 83 | 235
hachisu | 63 74 69 | 206
miyazawa | 76 57 79 | 212
yokomori | 95 89 81 | 265
nakamiti | 73 64 92 | 229 」
構造体ついての質問です。。
「学生の名前と国語、英語、数学の3科目の点数、合計点を保存するためのデータ構造を設計しなさい型名は StdData とすること。また、キーボードから人数と、人数分のそれらのデータを StdData 型の配列に格納し、配列の要素のデータを順に出力するプログラムを作成しなさい。」
こんな問題です。
こんな実行結果になります。
「
The number of students: 7
1: kim 82 57 74
2: otsuki 78 92 65
3: atsumi 88 64 83
4: hachisu 63 74 69
5: miyazawa 76 57 79
6: yokomori 95 89 81
7: nakamiti 73 64 92
name | jpn eng math| sum
kim | 82 57 74 | 213
otsuki | 78 92 65 | 235
atsumi | 88 64 83 | 235
hachisu | 63 74 69 | 206
miyazawa | 76 57 79 | 212
yokomori | 95 89 81 | 265
nakamiti | 73 64 92 | 229 」
Re:構造体
私の作ったプログラムです。
まだ、合計がでてなかっtりと未完成なのですが・・・・・
ここで、getdataの引数の事でコンパイル時にエラーが出てしまいました。
どう違うんでしょうか??
御指導お願いします。
まだ、合計がでてなかっtりと未完成なのですが・・・・・
#include <stdio.h> struct stddata{ char student_name[100]; /*生徒の名前*/ int jpn; /*国語の点数*/ int eng; /*英語の点数*/ int math; /*数学の点数*/ }; void getdata(struct stddata *sp,char *name,int jpn,int eng,int math); void printdata( struct stddata *sp ); int main( void ){ struct stddata student[20]; int i,n,jpn,eng,math; char name[100]; printf( "The number of students:" ); scanf("%d",&n); for(i=0;i<n;i++){ printf("%d:",i); scanf("%s %d %d %d",name,&jpn,&eng,&math); getdata(&name,jpn,eng,math); /* データ表示 */ } for(i=0;i<n;i++){ printdata(&student); } return 0; } void getdata(struct stddata *sp,char *name,int jpn,int eng,int math){ strcpy(sp->student_name,name); sp->jpn=jpn; sp->eng=eng; sp->math=math; } void printdata( struct stddata *sp ){ printf( "name | jpn eng math\n" ); printf( "%s %5d %4d %5d \n", sp->student_name,sp->jpn,sp->eng,sp->math); }
ここで、getdataの引数の事でコンパイル時にエラーが出てしまいました。
どう違うんでしょうか??
御指導お願いします。
Re:構造体
まず、そのエラーについてだけ答えます。
コンパイルすると、エラーメッセージがでますよね?
そのエラーメッセージをみてもらったらわかりますけど、
1>.\○○.cpp(25) : error C2660: 'getdata' : 関数に 4 個の引数を指定できません。
こんなエラーがでるはずです。
ここで、4つの引数が指定できないのならこの関数の仕様はどうなっているのかなと思ってみます。
プロトタイプ宣言は
void getdata(struct stddata *sp,char *name,int jpn,int eng,int math);
こうなっています。
全部で5つ引数があるはずの関数に4つの引数を持たせて呼んでいるのでだめですよと言われているのです。
コンパイルすると、エラーメッセージがでますよね?
そのエラーメッセージをみてもらったらわかりますけど、
1>.\○○.cpp(25) : error C2660: 'getdata' : 関数に 4 個の引数を指定できません。
こんなエラーがでるはずです。
ここで、4つの引数が指定できないのならこの関数の仕様はどうなっているのかなと思ってみます。
プロトタイプ宣言は
void getdata(struct stddata *sp,char *name,int jpn,int eng,int math);
こうなっています。
全部で5つ引数があるはずの関数に4つの引数を持たせて呼んでいるのでだめですよと言われているのです。
Re:構造体
ちょっと出かける用事があるので、先に答え書いておきますね。
そして、配列の特定の要素をポインタを使って操作するには
このようにします。
プログラムの意味がわかりますか?
お書きになったプログラムを急いで書き直してみました。
急いだので間違いがどこかにあるかもしれませんが、一応実行結果はうまくいきます。
試してみてください。
#include <stdio.h> void getname(char name[100]){ scanf("%s",name); return ; } void main(){ char name[100]; getname(name); printf("%s",name); }
そして、配列の特定の要素をポインタを使って操作するには
#include <stdio.h> void input(char *n){ *n='6'; return ; } void main(){ char name[100]="12345"; input(&name[2]); printf("%s",name); }
このようにします。
プログラムの意味がわかりますか?
お書きになったプログラムを急いで書き直してみました。
#include <stdio.h> #include <string.h> struct stddata{ char student_name[100]; /*生徒の名前*/ int jpn; /*国語の点数*/ int eng; /*英語の点数*/ int math; /*数学の点数*/ }; void getdata(struct stddata *sp,char *name,int jpn,int eng,int math); void printdata( struct stddata sp ); int main( void ){ struct stddata student[20]; int i,n,jpn,eng,math; char name[100]; printf( "The number of students:" ); scanf("%d",&n); for(i=0;i<n;i++){ printf("%d:",i); scanf("%s %d %d %d",name,&jpn,&eng,&math); getdata(&student,name,jpn,eng,math); /* データ表示 */ } printf( "\nname | jpn | eng | math\n" ); for(i=0;i<n;i++){ printdata(student); } return 0; } void getdata(struct stddata *sp,char *name,int jpn,int eng,int math){ strcpy(sp->student_name,name); sp->jpn=jpn; sp->eng=eng; sp->math=math; } void printdata( struct stddata sp ){ printf( "%-10s | %3d | %3d | %3d\n", sp.student_name,sp.jpn,sp.eng,sp.math); }
急いだので間違いがどこかにあるかもしれませんが、一応実行結果はうまくいきます。
試してみてください。
Re:構造体
バイトでかなり疲れて・・・・(笑)
今日1ゲンからだったしぃ。。。
おそくなりました★
こんなのを作りました。実行はできたんですが、内容的にどうでしょうか??
チェックお願いします。
見にくくて、ごめんんさぁーい。。お願いします。
今日1ゲンからだったしぃ。。。
おそくなりました★
こんなのを作りました。実行はできたんですが、内容的にどうでしょうか??
チェックお願いします。
#include <stdio.h> typedef struct{ char name[100]; int jpn; int eng; int math; }StdData; int getdata(StdData student_1[/url]); void printdata(int n,StdData student_2[/url]); int main(void){ StdData list[100]; int tensu; tensu=getdata(list); printdata(tensu,list); return 0; } int getdata(StdData student_1[/url]){ int num,count; printf("The number of students: "); scanf("%d",&num); for(count=0;count<num;count++){ printf("%d: ",count+1); scanf("%s %d %d %d",student_1[count].name,&student_1[count].jpn,&student_1[count].eng,&student_1[count].math); } return num; } void printdata(int n,StdData student_2[/url]){ int kazoeru,sum; printf(" name | jpn eng math|sum\n"); for(kazoeru=0;kazoeru<n;kazoeru++){ sum=student_2[kazoer[/url].jpn+student_2[kazoer[/url].eng+student_2[kazoer[/url].math; printf("%10s | %3d %3d %3d | %d\n",student_2[kazoer[/url].name,student_2[kazoer[/url].jpn,student_2[kazoer[/url].eng,student_2[kazoer[/url].math,sum); } }
見にくくて、ごめんんさぁーい。。お願いします。
Re:構造体
バイトお疲れ様です。
私も、新しいバイクを買う前は、毎日夜明けまでバイトをしていたので、よくわかります(_ _)
プログラムコードを拝見しましたけど、よいと思いますよ、特に間違っている箇所は無いと思います。
若干細かいところをいうと・・・。
①
見にくい^^;
>見にくくて、ごめんんさぁーい。。
そういえば初めて投稿してもらった時から微妙に字下げがおかしかったですよね^^;
Linux使ってるんでしたっけ?ってことはエディタはEmacsですか?
Emacsならそれぞれの行でTabキー押せば自動調整してくれるはずなんですけどねぇ><
例えばここ
空白が
2
4
4
4
5
になってます。
4
4
4
8
8
の方が綺麗に見えると思います。
②
後、関数はなるべく最後にはreturn文を書きましょう。
int関数ならreturn 0;(あるいは他の数値)と、void関数なら最後にreturn ;と。
③
もっとも深刻なのが、エラー処理をしていない点。
例えばscanfで4つのデータをとってきていますが、スペースを空け忘れたり、4つ以外のデータが入力されたり、数値部分に文字が入力されてもそのままになっていますので、
バッファのデータが狂うかもしれません。
http://www.pc.uec.ac.jp/sp/hshrkw/edu/p ... e1-22.html
このへんscanfを使う危険性が書かれています。
getchar関数で1文字ずつ判定していけばエラー処理も綺麗に行えるでしょう。
しかし全体的に大きな間違いは無いと思います。
確かまだプログラムを始めて1年もたってないんでしたよね。
頑張っていらっしゃいますね、これからも頑張ってください☆
私も、新しいバイクを買う前は、毎日夜明けまでバイトをしていたので、よくわかります(_ _)
プログラムコードを拝見しましたけど、よいと思いますよ、特に間違っている箇所は無いと思います。
若干細かいところをいうと・・・。
①
見にくい^^;
>見にくくて、ごめんんさぁーい。。
そういえば初めて投稿してもらった時から微妙に字下げがおかしかったですよね^^;
Linux使ってるんでしたっけ?ってことはエディタはEmacsですか?
Emacsならそれぞれの行でTabキー押せば自動調整してくれるはずなんですけどねぇ><
例えばここ
int kazoeru,sum; printf(" name | jpn eng math|sum\n"); for(kazoeru=0;kazoeru<n;kazoeru++){ sum=student_2[kazoer[/url].jpn+student_2[kazoer[/url].eng+student_2[kazoer[/url].math; printf("%10s | %3d %3d %3d |
空白が
2
4
4
4
5
になってます。
4
4
4
8
8
の方が綺麗に見えると思います。
②
後、関数はなるべく最後にはreturn文を書きましょう。
int関数ならreturn 0;(あるいは他の数値)と、void関数なら最後にreturn ;と。
③
もっとも深刻なのが、エラー処理をしていない点。
例えばscanfで4つのデータをとってきていますが、スペースを空け忘れたり、4つ以外のデータが入力されたり、数値部分に文字が入力されてもそのままになっていますので、
バッファのデータが狂うかもしれません。
http://www.pc.uec.ac.jp/sp/hshrkw/edu/p ... e1-22.html
このへんscanfを使う危険性が書かれています。
getchar関数で1文字ずつ判定していけばエラー処理も綺麗に行えるでしょう。
しかし全体的に大きな間違いは無いと思います。
確かまだプログラムを始めて1年もたってないんでしたよね。
頑張っていらっしゃいますね、これからも頑張ってください☆
Re:構造体
見にくいって言われちゃった(笑)
ですよねぇー!!!アタシ頑張りましたもん。。。
昨日とは見違えましたよね!!!
なるほど、return省略しない方がいいんですねぇー。
なんか学校だと先生が強制てきにしろ!!とか言うんですよ。。。
それで、するべきところとかがごっちゃになってしまって。。。
あと1つ質問なんですが、
これを今度、合計点の高い順にソートした結果を 出力するように修正する場合って。。。
どうすればいいんでしょうか?バブルソートを考えてるんですが・・・
void bubbleSort(int student_2[/url],int num){
int i,j;
for(i=num-1;i>=0;i--){
for(j=0;j<i;j++){
if(student_2[j].>student_2[j+1]){
swap(student_2[j].sum);
なんかこんなん形は作ったんですが・・・よくわからなくて・・・
ですよねぇー!!!アタシ頑張りましたもん。。。
昨日とは見違えましたよね!!!
なるほど、return省略しない方がいいんですねぇー。
なんか学校だと先生が強制てきにしろ!!とか言うんですよ。。。
それで、するべきところとかがごっちゃになってしまって。。。
あと1つ質問なんですが、
これを今度、合計点の高い順にソートした結果を 出力するように修正する場合って。。。
どうすればいいんでしょうか?バブルソートを考えてるんですが・・・
void bubbleSort(int student_2[/url],int num){
int i,j;
for(i=num-1;i>=0;i--){
for(j=0;j<i;j++){
if(student_2[j].>student_2[j+1]){
swap(student_2[j].sum);
なんかこんなん形は作ったんですが・・・よくわからなくて・・・
Re:構造体
あら・・voidの時はreturn文は書かない方がいいんでしょうか?
私が愛用していた入門書には全てreturnを書いた方がいいと書いてあったので、
ずっとそうしてきましたが、そうではなかったのですか。
ずっと今までそうしてきたので、関数の終わりに何もないと違和感を感じるようになりました^^;
プログラムのコードは短いに越した事は無いので、書かなくていいものは書かない方がいいかもしれないですね。
また、Justyさんのおっしゃる方法が一般的なのでしょうから、一般的な方法に合わせる方が可読性もあがると思いますし、
そちらに合わせた方がいいと思います。
すみませんでした(_ _|||)
私が愛用していた入門書には全てreturnを書いた方がいいと書いてあったので、
ずっとそうしてきましたが、そうではなかったのですか。
ずっと今までそうしてきたので、関数の終わりに何もないと違和感を感じるようになりました^^;
プログラムのコードは短いに越した事は無いので、書かなくていいものは書かない方がいいかもしれないですね。
また、Justyさんのおっしゃる方法が一般的なのでしょうから、一般的な方法に合わせる方が可読性もあがると思いますし、
そちらに合わせた方がいいと思います。
すみませんでした(_ _|||)
Re:構造体
>これを今度、合計点の高い順にソートした結果を 出力するように修正する場合って。。。
>どうすればいいんでしょうか?
それには合計点を格納するための変数を構造体にもう一つ追加する必要がありますが、それはコードを拝見する限りは既に用意されているようですね。
バブルソートは簡単ですし、ウェブにサンプルが沢山ありますので、
それを見ながら実装してみてはいかがでしょうか。
http://www.ics.kagoshima-u.ac.jp/~fuchi ... -sort.html
http://www1.cts.ne.jp/~clab/hsample/Sort/Sort1.html
>どうすればいいんでしょうか?
それには合計点を格納するための変数を構造体にもう一つ追加する必要がありますが、それはコードを拝見する限りは既に用意されているようですね。
バブルソートは簡単ですし、ウェブにサンプルが沢山ありますので、
それを見ながら実装してみてはいかがでしょうか。
http://www.ics.kagoshima-u.ac.jp/~fuchi ... -sort.html
http://www1.cts.ne.jp/~clab/hsample/Sort/Sort1.html
Re:構造体
>return文を書かない方が一般的だと聞いてなんとなくすっきりしました
あー、一般的とまでは断定できません。
自分の周りではあまりいない、というだけで。
ひょっとしたら時流は returnを使う方に流れているのかもしれませんよ。
他の人の意見を聞いてみたいところです。
>メイン関数にvoidを使うべきではないのでしょうか?
結論から言えば、YESです。
このあたりはちょっとだけ複雑です。
Cの場合 main関数の型に関しては必ず以下の4つでなければなりません。
1 intを戻り値にして引数なし。
int main(void)
2 intを戻り値にして、2つに引数を持つ
int main(int, char *[/url])
3 1や 2と等価な方法
int main(int, char **)
typedef int int_t;
int_t main(int, char *[/url])
とか
4 1~3以外の処理系定義
なので、原則的には intが戻り値ではあるものの、4を適用した処理系では
voidなのかもしれませんし、極端な話 floatかもしれません。
ちなみに C++ではまたちょっと違いますが、intを戻り値とすることが基本となっています。
戻り値をホスト環境(OS)がどう見ているかにもよります。
ひょっとしたら 0以外を返したら、OSをシャットダウンしてしまう環境があるかもしれません。
そんなとき、戻り値を void型にしてしまって不定な値をホスト側が戻り値として
解釈されてしまったら・・・・。
まぁ、そんなわけで、原則である intを戻り値にしておけばほとんどの環境で
大丈夫だろうというわけです。
ただ、現実的には巷のメジャーな環境では 戻り値が voidであっても
何事もなかったかのように動いてはいるので、実装的には問題ないとは言えなくもないですが、
教える側としてはかなり難アリなのではないでしょうか。
あー、一般的とまでは断定できません。
自分の周りではあまりいない、というだけで。
ひょっとしたら時流は returnを使う方に流れているのかもしれませんよ。
他の人の意見を聞いてみたいところです。
>メイン関数にvoidを使うべきではないのでしょうか?
結論から言えば、YESです。
このあたりはちょっとだけ複雑です。
Cの場合 main関数の型に関しては必ず以下の4つでなければなりません。
1 intを戻り値にして引数なし。
int main(void)
2 intを戻り値にして、2つに引数を持つ
int main(int, char *[/url])
3 1や 2と等価な方法
int main(int, char **)
typedef int int_t;
int_t main(int, char *[/url])
とか
4 1~3以外の処理系定義
なので、原則的には intが戻り値ではあるものの、4を適用した処理系では
voidなのかもしれませんし、極端な話 floatかもしれません。
ちなみに C++ではまたちょっと違いますが、intを戻り値とすることが基本となっています。
戻り値をホスト環境(OS)がどう見ているかにもよります。
ひょっとしたら 0以外を返したら、OSをシャットダウンしてしまう環境があるかもしれません。
そんなとき、戻り値を void型にしてしまって不定な値をホスト側が戻り値として
解釈されてしまったら・・・・。
まぁ、そんなわけで、原則である intを戻り値にしておけばほとんどの環境で
大丈夫だろうというわけです。
ただ、現実的には巷のメジャーな環境では 戻り値が voidであっても
何事もなかったかのように動いてはいるので、実装的には問題ないとは言えなくもないですが、
教える側としてはかなり難アリなのではないでしょうか。