こんにちは。C言語の構造体について質問があります。
下記のようなコードを書いて構造体の動作を確認しています。
疑問点は、コードの下から3行目と4行目の内容です。
構造体の実体をPrintfしたら、構造体の先頭にあるメンバ変数の値だけが出力されると思っていたら、
メンバ変数が全て出力できました。
この動きがよくわからないのですが、
構造体の中身を出力しようとしたときに、
具体的なメンバ変数を指定しない場合は、全てのメンバ変数の値が出力される仕様になっているという事なのでしょうか?
もしどなたか詳しい方がいらっしゃいましたら、教えていただけますと幸いです。
C
1#include <stdio.h> 2 3struct animal 4{ 5 /* data */ 6 int eye; 7 double weight; 8}; 9 10int main(void){ 11 struct animal animal = {0}; 12 struct animal *panimal = &animal; 13 panimal->eye=11; 14 15 //構造体animalの実体のメンバ変数eyeにアクセスしています 16 //全部11が出力されます 17 printf("%d\n",panimal->eye); 18 printf("%d\n",animal.eye); 19 printf("%d\n",(*panimal).eye); 20 21 //構造体animalの実体のメンバ変数eyeのアドレスを表示しています 22 //全部同じアドレスが出力されます 23 printf("%p\n",panimal); 24 printf("%p\n",&(panimal->eye)); 25 printf("%p\n",&animal); 26 printf("%p\n",&animal.eye); 27 28 //↑ここまでは想定していた動きでした。 29 30 //↓これら2つが何が起きているのか分かりません…… 31 printf("%d,%f\n",*panimal); //←*panimalはアドレス&animalが指す値なので、メンバ変数eyesの値だけが出力されるはずではないですか? 32 //しかし実際は、-Wformatオプションでビルドするとワーニングが出るものの、なぜかメンバ変数が2つとも読めました。理由がわかりません。 33 printf("%d,%f\n",animal); //←もしかしてこれも行けるかもと思って書いてみました、これもメンバ変数が2つとも読めて、何が起きているのかわかりません。 34 35 return 0; 36}
追記します。
構造体を配列として宣言して使った場合、メンバ変数を指定せずにPrintfすることはできませんでした。
C
1#include <stdio.h> 2 3//構造体の型宣言 4struct student{ 5 int no; // 学籍番号 6 char name[256]; // 氏名 7 int year; // 学年 8 char s_class[256]; // クラス 9}; 10 11int main(void){ 12 int i; 13 //構造体の宣言と初期化の代入 14 struct student students[4] = { 15 {1, "nakano", 1, "c"}, 16 {2, "ooisi", 2, "b"}, 17 {3, "okamoto", 1, "a"}, 18 {4, "minabe", 2, "a"}, 19 }; 20 21 for(i = 0; i < 4; i++) { 22 //結果の出力 23 //コメントアウトしているコレは意図通りに要素を表示してくれます↓ 24 //printf("%d,%s,%d,%s\n", students[i].no, students[i].name, students[i].year, students[i].s_class); 25 26 //↓これは同じようにワーニングが出るのですが、実行してもデータは取れませんでした。 27 printf("%d,%s,%d,%s\n",students[i]); 28 } 29 30 return 0;
更に追記します。
jimbeさんにコメントいただいて、
仮に配列みたいにスタックしていて、本来はエラー吐きそうな実装だけれども、たまたまうまくいっているだけと考えると、
ポインタをインクリメントしたり、糖衣構文じゃない配列の値出力の書き方でデータが読み出せるんじゃないかと思って、
C
1//ポインタをインクリメントするパターン 2printf("--%d\n",*(&animal+0)); 3printf("--%f\n",*(&animal+1)); 4//糖衣構文じゃない配列の書き方 5printf("%d\n",0[&animal]); 6printf("%f\n",1[&animal]);
こんな文を追記してみたところ、私の環境では、両方とも11と0.0が出力されました!(びっくり!)
確かにこれが動いたということは、スタックフレームで実現されているのかもしれませんね。
更に配列と同じ書き方もしてみましたが、さすがにこちらはエラーが出力されました。
C
1 //これは動かない 2 printf("%d\n",&animal[0]); 3 printf("%f\n",&animal[1]);
初心者なものでちょっと不安なのですが、
基本的には、「C言語の構造体を、メンバ変数の指定なしでPrintfしたりしない。Printfするときは必ずメンバ変数を指定する」という風に覚えておけばいいんですかね?
それとも、日常的にprintf("%d,%f\n",animal);的な、メンバ変数を指定しない出力する文を書いたりされますか?
回答5件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。