2

私はそれを理解していないので、誰かが次の引用を理解するのを手伝ってくれませんか:

構造体またはクラスの先頭に対するメンバーのオフセットが 128 未満の場合、データ メンバーにアクセスするためのコードはよりコンパクトになります。例:

class S2{
    public:
    int a[100];   //400 bytes. first byte at 0, last byte at 399
    int b;        //4 bytes.   first byte at 400, last byte at 403
    int ReadB() {return b;}
};

ここで b のオフセットは 400 です。ポインターまたは ReadB() などのメンバー関数を介して b にアクセスするコードは、ポインターに 4 バイトのオフセットを追加する必要があります。a と b を交換すると、1 バイトの符号付き整数オフセットで両方にアクセスできます

この 1 バイトの値はどこから来たのですか? a と b が入れ替わった場合、b はバイト 0 から始まり、a はバイト 4 から始まりますか?

編集:私の間違い、配列サイズは100になるはずでした

4

3 に答える 3

4

[元の質問がからa[400]に変更された後に編集されましたa[100]。]

彼らのポイントは正しいです:

  • 現状のS2構造では、a[100]100個の4バイト整数です。実際には400バイトの長さです。aしたがって、オフセットは0〜399です。 b(ここでも4バイト整数)は、(少なくとも)400〜403のオフセットに配置されます。

    Offset  data
    000-399 a[0]-a[99] inclusive
    400-403 b
    
  • の順序を入れ替えるab、のオフセットはa0〜3にbなり、4〜403になります。

    Offset  data
    000-003 b
    004-403 a[0]-a[99] inclusive
    
  • どちらの場合も、必要なオフセットの潜在的な範囲のために、アレイの初期であっても、アクセスbには16ビットのオフセットが使用されます。2番目の場合のみ、アクセスaは8ビットオフセットで実行できます(CPUに依存)。これはより高速になる可能性があります(CPUに依存します)。クラスが格納されている場所の開始と変数が格納されている場所の間のオフセットを格納するために必要なビット数がすべてです。

お役に立てれば。私はここで4バイトのintを想定しています(これはかなり一般的ですが、普遍的ではありません)、元の引用ではそうです。

于 2013-03-20T16:43:29.607 に答える
4

彼らが指摘しようとしているのは、構造体の先頭からbメンバーまでのバイト単位のオフセットが 255 より大きいため、ベース ポインターに 8 ビットを 1 回追加しただけでは計算できないということです。より多くのビットが必要です:

Offset           Member
0                a    // offset always zero
100*sizeof(int)  b    // offset guaranteed to be at 100*sizeof(int)

フィールドの順序を逆にする

0                b    // offset always zero
sizeof(int)*     a    // offset always sizeof(int) + potential padding

最初のケースでのアクセスbには、ベース ポインター + 少なくとも 16 ビットのオフセットを必要とする長さの値が必要です (最小エンティティが 8 ビットであると仮定します)。2 番目のケースでは、bとの両方aが、8 ビットに収まる構造体のベース アドレスのオフセット内にあります。

そして、著者が少なくとも潜在的なメンバーのパディングについて言及しなかったことは、やや誤解を招くと思います。

編集member の OP の 400 から 100 への配列スロットの変更を反映するように更新されましたb。これが 16 ビットの実装int値を持つ打ちのめされた組み込みシステムである場合、著者が指摘するのは間違っていることに注意してください。その場合、配列は100 * 2- バイト幅になり、8 ビットのオフセットが 2 番目のメンバーに到達できるようになります。4 バイト (またはそれ以上) の実装int値を持つシステムの場合、作成者の指摘は有効です。

于 2013-03-20T16:50:50.777 に答える
0

オフセットを保存するために必要なスペースについて話しています。与えられた例では、aはオフセット0(表現するのに1バイトかかります)にbあり、オフセット400 * sizeof(int)(おそらく実際には4バイトかかります)にあります。それらを交換すると、aオフセット0(1バイト)になりb、オフセット4(1バイト)になります。

于 2013-03-20T16:43:49.437 に答える