以下是有问题的代码
#include <stdio.h>
struct test {
unsigned char t;
unsigned short u;
unsigned char v;
};
int main ()
{
struct test * a = (void *) 0x1000;
printf("%x %p %p\n",
sizeof(struct test),
a + sizeof(struct test),
a - sizeof(struct test));
return 0;
}
sizeof(struct test)打印6,所以我期待看到:
6 0xffa 0x1006
相反,我得到
6 0x1024 0xfdc
我上次检查时,0x24或36,不等于6.它甚至没有与我能说的任何东西对齐。我完全失去了。
有人可以向我解释为什么我会得到这些价值观吗?
答案 0 :(得分:17)
问题在于,当你进行指针运算时,它会增加数据类型大小的多个。
所以你实际做的是按sizeof(struct test)
的平方加入。
从sizeof(struct test) = 6
开始,您将地址递增6 * 6 = 36
。因此,您获得0x1024
和0xfdc
代替0x1006
和0xffa
的原因。 (您还切换了+
和-
,但这是一件小事。)
相反,只需这样做:
printf("%x %p %p\n",
sizeof(struct test),
a + 1,
a - 1);
答案 1 :(得分:4)
当您像这样进行指针运算时,您可以向前或向后移动该数量的元素,就好像该变量位于数组中一样。所以你真的只想使用a + 1
和a - 1
,每次都要提前6个字节。
重要事项:请记住,编译器可以在结构中添加填充以帮助进行对齐。不要只是假设因为你有两个单字节字符和一个两字节短,你的结构将是4字节大小---这不是这里的情况。 (事实上,不要以为你知道char或short的大小;我之前看过2字节字符。)
答案 2 :(得分:2)
我认为您正在寻找a + 1
和a - 1
。
(a + x)
与&a[x]
相同。
答案 3 :(得分:1)
你有一个打字的指针。
所以当你递增1时(即a + 1
),就意味着a + sizeof(type)
。
所以a + sizeof(type)
= a + sizeof(type) * sizeof(type)
= a + 6 * 6
(在您的情况下为sizeof(test)= 6)
这是你从0x24
或36获得的地方。