- 締切済み
構造体とポインタ
演習問題を解いていて「構造体ポインタの指定の方法」で理解できない部分があったので、質問させていただきます。 その内容は、メイン関数で「scanf」で入力させた値を仮引数として計算する関数に送って計算し、メイン関数で表示処理を行うというものを、構造体とポインタを使って作るというものです。 とりあえずプログラムは以下のとおりになりました。 (字下げしたものが、下部のURL先にあります) #include <stdio.h> /***構造体***/ struct test{ int a; int b; }syoki[2] = { {0,0}, {0,0} }; /***値をプラスする関数***/ void kansu(struct test *no){ no->a++; no->b++; } /***メイン関数***/ void main(){ int nomber; //無限ループ for(;;){ printf("値を追加する番号を指定してください\n"); printf("(入力する値は、0か1)→"); scanf("%d", &nomber); //関数を呼び出す kansu(&nomber); //画面表示 printf("入力番号: %d\n",syoki); printf("値1: %d\n",syoki->a); printf("値2: %d\n",syoki->b); } } VisualStudio.NETのエラー内容では 「'int *__w64 ' から 'test *' に変換できません」 と表記されています。おそらくメイン関数で指定した「nomber」がint型では駄目だというのはわかるのですが、それでは他に何を指定すればいいのかわからないのです。 もしよければ、アドバイスをいただけると嬉しいです。 よろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- PG_RankB
- ベストアンサー率40% (12/30)
何度も申し訳無いです。が、回答してしまった以上責任を持ちたいので; まず、上記コードに対してのコメントですが、scanfで入力した値を使用するのは、syokiの、0と1、どちらにするのか。と言うインデックスとしての役割ですね? その場合、//画面表示 printf("入力番号: %d\n",syoki); は、 printf("入力番号: %d\n",nomber); となります。syokiは構造体の本体ですので、%dで値を参照すべき物ではありません。 printf("値1: %d\n",syoki->a); printf("値2: %d\n",syoki->b); は、これではsyoki[0]とsyoki[1]を区別して参照する事が出来ませんので、 printf("値1: %d\n",syoki[nomber].a); printf("値2: %d\n",syoki[nomber].b); とする事で、nomberに入力した値の方を参照出来る様になります。 また、先にも述べましたが、for()で無限ループするなら、breakやreturnで抜ける処理を行わないと、文字通り、永遠に処理が終わりません。 また、今回はサンプルに従うので良いですが、 printf("値を追加する番号を指定してください\n"); printf("(入力する値は、0か1)→"); とありますが、これは実際に0か1以外の値だった場合、if()なのではじく例外処理を実装しなければいけません。 特に、syoki[nomber].aとしている場合、nomberに3と入れれば、無いはずのsyoki[3].aを参照してしまいますので。 それを踏まえて、簡単なサンプルを書きました。参考にして下されば幸いです。 ↓以下サンプル↓ #include <stdio.h> /***構造体***/ struct test{ int a; int b; }syoki[2] = { {0,0}, {0,0} }; /***値をプラスする関数***/ void kansu(struct test *no){ no->a++; no->b++; } /***メイン関数***/ void main(){ int i; int number; for(i=0;i<5;i++){ printf("値を追加する番号を指定してください\n"); printf("(入力する値は、0か1)→"); scanf("%d", &number); //バグ回避 if ( number != 0 && number != 1 ) { printf( "入力値のエラー文等をここに\n" ); continue; } //関数を呼び出す kansu(&syoki[number]); //画面表示 printf("入力番号: %d\n", number ); printf("値1: %d\n",syoki[number].a); printf("値2: %d\n",syoki[number].b); } } 最後に、重箱の隅をつつく様な発言になり申し訳ないのですが、 nomberと言う変数名について、恐らく数・番号と言ったものを英語にしていると思うのですが、 nomber・・・× number・・・○ です。
- PG_RankB
- ベストアンサー率40% (12/30)
?すみません、よく見てみたら、コード内容に不明な点がいくつかありますね・・・ 先の回答はコンパイルエラーや警告を除去する内容でしたが、今ひとつやりたい事が鮮明になりません。 まず、for()で無限ループする所が疑問なのですが・・・?
- PG_RankB
- ベストアンサー率40% (12/30)
kansu()の定義は /***値をプラスする関数***/ void kansu(struct test *no){ no->a++; no->b++; } となっています。仮引数がint型では無く、構造体のtest型のポインタなので、 //関数を呼び出す kansu(&nomber); となっていますが、 kansu( shoki ); とすれば良いです。
お礼
PG_RankB様、御丁寧に何度もお返事ありがとうございます。 お礼してもしきれないほど、感謝しています。 試してみたところ、無事確認することができました。 やはり、バグ回避が無いとプログラム的に・・・ですよね。 これを踏まえたうえで、また新たに勉強に励みたいと思います。 本当にありがとうございました。