web-dev-qa-db-ja.com

構造体のポインタ演算

1つのdouble変数と3つのint変数(全部で4つの変数)を含む構造体定義が与えられた場合、pが値0x1000のこの構造体へのポインターである場合、p ++にはどのような値がありますか?

これは宿題の問題ではないので、心配しないでください。テストの準備をしているだけで、この練習問題を理解できません。ありがとう

これはCです。はい、増分した後のpの値が必要です。これは32ビットマシンです

15
user950891
struct foobar *p;
p = 0x1000; 
p++;

と同じです

struct foobar *p;
p = 0x1000 + sizeof(struct foobar);
20
tangrs

答えはそれが少なくともであるということです

_sizeof(double) + (3*sizeof(int))
_

それが「少なくとも」である理由は、コンパイラーが、アライメントの制約に合うように、基礎となるアーキテクチャーの必要に応じて、多かれ少なかれ自由にパディングを追加できるからです。

たとえば、古いCDCマシンのように、64ビットのWordを搭載したマシンがあるとします。 (地獄、それらのいくつかは60ビットの単語を持っていたので、それはさらに奇妙になるでしょう。)さらに、そのマシンでは、sizeof(double)が64ビットであり、sizeof(int)が16ビットであると仮定します。次に、コンパイラは構造体を次のようにレイアウトします。

_| double     | int | int | int | 16 bits padding |
_

構造体全体が2つのメモリ参照でマシンを通過できるようにするため、シフトや混乱は必要ありません。その場合、sizeof(yourstruct_s)は16になります。ここで、sizeof(double)+ (3*sizeof(int))はのみです。 48 14.14。

更新

これは32ビットマシンでも当てはまる可能性があることに注意してください。3ワードに合わせるためにパディングが必要になる場合があります。バイトまでアドレス指定しない最新のマシンを知らないので、今は例を見つけるのは難しいかもしれませんが、古いアーキテクチャの多くはこれを必要とするでしょう。

3
Charlie Martin

ポインタ演算は、ポインタタイプのサイズの単位で行われます。

したがって、構造体へのポインタに対してp++を実行すると、pはsizeof *pバイト進みます。つまり、sizeof演算子を使用して、構造体の大きさをコンパイラに尋ねるだけです。

3
nos
p = p + sizeof(YourStruct)

パディングをオフにしない場合、コンパイラはどのsizeofが返されるかを自由に決定できます。

2
James

データ型のベースアドレスの増分は、ベースアドレス+ sizeof(データ型)に等しい

0
Saurabh Yadav