質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

4135閲覧

アドレスが同じになる(構造体)

ikuo-biyori

総合スコア56

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2016/12/19 00:26

いつもお世話になっています。C言語初心者でただいま勉強中です。構造体へのポインタのアドレスについて質問させていただきます。data[0],data[1]のアドレスを調べたいんですが、なぜかdata[0
]とdata[1]のアドレスが同じになってしまいます。どのようにすれば正しいアドレスが得られますか?教えて下さい。よろしくお願いします。以下がコードです。

C言語

1コード
#include<stdio.h> typedef struct{ int id; /* ID */ char name[20]; /* 名前 */ int score; /* 点数 */ char grade; /* 成績 */ } Record; /* 以下の構造体の初期化はmain()の中に書くこと */ int main() { int i; Record data[2]={ {1,"Aki",80,'A'}, {2,"Takero",75,'B'},};/*構造体の初期化*/ Record *p=data,*q;/*構造体へのポインタの初期化*/ for(i=0;i<2;i++){/*ポインタpがdata0,data1を表す出力*/ printf("%d\n",(*(p+i)).id); printf("%s\n",(*(p+i)).name); printf("%d\n",(*(p+i)).score); printf("%c\n",(*(p+i)).grade); printf("構造体型data[%d]のサイズは%dバイトです。\n",i,sizeof(p+i)); printf("構造体data[%d]のアドレスは%pです。\n",i,(p+i)); } for(i=0;i<2;i++){/*構造体へのポインタからそれぞれのメンバにアクセスして出力*/ printf("%d\n",(p+i)->id); printf("%s\n",(p+i)->name); printf("%d\n",(p+i)->score); printf("%c\n",(p+i)->grade); printf("構造体型data[%d]のサイズは%dバイトです。\n",i,sizeof(p+i)); printf("構造体data[%d]のアドレスは%pです。\n",i,p+i); } int z=0; for(q=p;q<p+2;q++){ /*ポインタが何も指していないところ(data0 ,data1の次の場所のところになる)までループ*/ printf("%d\n",(*q).id); printf("%s\n",(*q).name); printf("%d\n",(*q).score); printf("%c\n",(*q).grade); if(z==0){ printf("構造体型data[%d]のサイズは%dバイトです。\n",z,sizeof(q)); printf("構造体data[%d]のアドレスは%pです。\n",z,&q); } else if(z==1){ printf("構造体型data[%d]のサイズは%dバイトです。\n",z,sizeof(q)); printf("構造体data[%d]のアドレスは%pです。\n",z,&q); } z++; } int j=0; for(q=p;q<p+2;q++){ /*ポインタが何も指していないところ(data0 ,data1の次の場所のところ)までループ*/ /*構造体へのポインタからそれぞれのメンバにアクセスして出力*/ printf("%d\n",q->id); printf("%s\n",q->name); printf("%d\n",q->score); printf("%c\n",q->grade); if(j==0){ printf("構造体型data[%d]のサイズは%dバイトです。\n",j,sizeof(q)); printf("構造体data[%d]のアドレスは%pです。\n",j,&q); } else if(j==1){ printf("構造体型data[%d]のサイズは%dバイトです。\n",j,sizeof(q)); printf("構造体data[%d]のアドレスは%pです。\n",j,&q); } j++; } // for(i=0;i<2;i++){ // printf("構造体型data%dのサイズは%dバイトです。\n",i,sizeof(*p)); // } return 0; }

実行結果
1
Aki
80
A
構造体型data[0]のサイズは8バイトです。
構造体data[0]のアドレスは0x7fff4fe94bb0です。
2
Takero
75
B
構造体型data[1]のサイズは8バイトです。
構造体data[1]のアドレスは0x7fff4fe94bd0です。
1
Aki
80
A
構造体型data[0]のサイズは8バイトです。
構造体data[0]のアドレスは0x7fff4fe94bb0です。
2
Takero
75
B
構造体型data[1]のサイズは8バイトです。
構造体data[1]のアドレスは0x7fff4fe94bd0です。
1
Aki
80
A
構造体型data[0]のサイズは8バイトです。
構造体data[0]のアドレスは0x7fff4fe94b98です。
2
Takero
75
B
構造体型data[1]のサイズは8バイトです。
構造体data[1]のアドレスは0x7fff4fe94b98です。
1
Aki
80
A
構造体型data[0]のサイズは8バイトです。
構造体data[0]のアドレスは0x7fff4fe94b98です。
2
Takero
75
B
構造体型data[1]のサイズは8バイトです。
構造体data[1]のアドレスは0x7fff4fe94b98です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

こんにちは。

結果を良く見ましょう。data[0]とdata[1]のアドレスは異なっていますよ。

構造体data[0]のアドレスは0x7fff4fe94bb0です。
構造体data[1]のアドレスは0x7fff4fe94bd0です。

差は0x20=32バイトあります。つまり、Recordのサイズが32バイトということです。
恐らくint型が4バイトの環境と思われますので、下記計算です。

id 4バイト
name 20バイト
score 4バイト
grade 1バイト
パディング 3バイト

パディングはその構造体内部の全ての変数についてアクセスが遅くなったり、アクセスできなったりしないようそれぞれの変数の型のアライメント境界に合わせるように埋められます。今回はint型がそれに該当し、4バイト単位で位置合わせ(アライメント)されます。

投稿2016/12/19 02:30

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

printf("%p", &q)となっていますが、これだと**q自体のアドレス**を表示してしまうので、qの中身のアドレスを表示したいならprintf("%p", q)が適当です。

あと、sizeof(ポインタ)とするとポインタ自体のサイズを返します。ポインタの指す先のサイズはsizeof(*ポインタ)のようにして取得して下さい(8バイトではint2個しか入らないでしょうし、明らかに違います)。

投稿2016/12/19 00:35

maisumakun

総合スコア145123

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikuo-biyori

2016/12/19 00:46

#include<stdio.h> typedef struct{ int id; /* ID */ char name[20]; /* 名前 */ int score; /* 点数 */ char grade; /* 成績  */ } Record; /* 以下の構造体の初期化はmain()の中に書くこと */ int main() { int i; Record data[2]={ {1,"Aki",80,'A'}, {2,"Takero",75,'B'},};/*構造体の初期化*/ Record *p=data,*q;/*構造体へのポインタの初期化*/ for(i=0;i<2;i++){/*ポインタpがdata0,data1を表す出力*/ printf("%d\n",(*(p+i)).id); printf("%s\n",(*(p+i)).name); printf("%d\n",(*(p+i)).score); printf("%c\n",(*(p+i)).grade); printf("構造体型data[%d]のサイズは%dバイトです。\n",i,sizeof(*(p+i))); printf("構造体data[%d]のアドレスは%pです。\n",i,(p+i)); } for(i=0;i<2;i++){/*構造体へのポインタからそれぞれのメンバにアクセスして出力*/ printf("%d\n",(p+i)->id); printf("%s\n",(p+i)->name); printf("%d\n",(p+i)->score); printf("%c\n",(p+i)->grade); printf("構造体型data[%d]のサイズは%dバイトです。\n",i,sizeof(*(p+i))); printf("構造体data[%d]のアドレスは%pです。\n",i,(p+i)); } int z=0; for(q=p;q<p+2;q++){ /*ポインタが何も指していないところ(data0 ,data1の次の場所のところになる)までループ*/ printf("%d\n",(*q).id); printf("%s\n",(*q).name); printf("%d\n",(*q).score); printf("%c\n",(*q).grade); if(z==0){ printf("構造体型data[%d]のサイズは%dバイトです。\n",z,sizeof(*q)); printf("構造体data[%d]のアドレスは%pです。\n",z,q); } else if(z==1){ printf("構造体型data[%d]のサイズは%dバイトです。\n",z,sizeof(*q)); printf("構造体data[%d]のアドレスは%pです。\n",z,q); } z++; } int j=0; for(q=p;q<p+2;q++){ /*ポインタが何も指していないところ(data0 ,data1の次の場所のところ)までループ*/ /*構造体へのポインタからそれぞれのメンバにアクセスして出力*/ printf("%d\n",q->id); printf("%s\n",q->name); printf("%d\n",q->score); printf("%c\n",q->grade); if(j==0){ printf("構造体型data[%d]のサイズは%dバイトです。\n",j,sizeof(*q)); printf("構造体data[%d]のアドレスは%pです。\n",j,q); } else if(j==1){ printf("構造体型data[%d]のサイズは%dバイトです。\n",j,sizeof(*q)); printf("構造体data[%d]のアドレスは%pです。\n",j,q); } j++; } // for(i=0;i<2;i++){ // printf("構造体型data%dのサイズは%dバイトです。\n",i,sizeof(*p)); // } return 0; } 直してみたんですが、まだアドレスが変わりません。サイズは32バイトとなったんですが。どこがいけませんか?
maisumakun

2016/12/19 00:49

サイズは32バイトで正しいです(「アライメント」といって、データの入らない隙間ができますが、構造体のサイズはそこまで含めて数えます)。
ikuo-biyori

2016/12/19 00:55

アドレスは、同じになったんですが、あっていますか?
ikuo-biyori

2016/12/19 09:27

アドレスちゃんと変わってました。教えていただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問