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 字节 int)将(至少)放置在 400-403 的偏移量处:

    Offset  data
    000-399 a[0]-a[99] inclusive
    400-403 b
    
  • 如果您要交换的顺序ab偏移量a将是 0-3 和b将是 4-403:

    Offset  data
    000-003 b
    004-403 a[0]-a[99] inclusive
    
  • 在这两种情况下,访问b都将使用 16 位偏移量,即使在数组的早期也是如此,因为可能需要偏移量范围。仅在第二种情况下,a可以使用 8 位偏移(取决于 CPU)进行访问。这可以更快(取决于 CPU)。这完全是关于存储类存储位置和变量存储位置之间的偏移量所需的位数。

希望这可以帮助。我在这里假设 4 字节整数(这很常见,但不是通用的),因为我认为原始引用它。

于 2013-03-20T16:43:29.607 回答
4

他们试图指出的是,从结构开头到b成员的偏移量(以字节为单位)> 255,因此不能用基指针的单个 8 位加法来计算。需要更多位:

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 位)。在第二种情况下,两者ba都在适合 8 位的结构基地址的偏移量之内。

而且我发现这有点误导作者至少没有提到潜在的成员填充。

编辑更新以反映 OP 从 member 的 400 到 100 个数组插槽的更改b。应该注意的是,如果这是一些具有 16 位实现int值的被破坏的嵌入式系统,作者指出的将是错误的。在这种情况下,数组将是100 * 2- 字节宽,这仍然允许 8 位偏移量到达第二个成员。对于具有 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 回答