我希望看到p和& atbl [1]打印相同的值(元素1的位置)但它不同
struct a {
unsigned int el[4];
};
struct a atbl[3] = {
{0x12131415, 0x01030507, 0x01030507, 0x16171819},
{0xa2a3a4a5, 0x02020202, 0x02020202, 0xa6a7a8a9},
{0xb2c3d4e5, 0x02020202, 0x02020202, 0x0badcafe},
};
struct a * p;
// read address of element 1 in atbl
p = (atbl + (1 * sizeof(struct a)));
printf("%08x %08x %08x %08x %08x\n", p, atbl, &atbl[0], &atbl[1], &atbl[2]);
但我得到以下结果:
p - dae83240
atbl - dae83140
& atbl [0] - dae83140
& atbl [1] - dae83150
& atbl [2] - dae83160
任何提示?
答案 0 :(得分:4)
// read address of element 1 in atbl
p = (atbl + (2 * sizeof(struct a)));
这应该是:
p = atbl + 1;
将一个添加到已指向第一个条目的内容将使其指向第二个条目。因此,添加两个会使它指向第三个条目。您希望它指向第二个条目,因此您需要添加一个。
此外,您不会乘以大小,因为指针已经知道它指向的东西的大小。添加一个已经指向下一个对象。
答案 1 :(得分:3)
指针算法自动计算指向对象的大小;您不需要乘以sizeof(struct a)
。
atbl
是类型为struct a*
的指针。 atbl + 2
点{2} struct a
个元素超出atbl
指向的地址。
另外,不要使用%x
来打印指针值;相反,将指针值强制转换为void*
并使用%p
。
答案 2 :(得分:1)
而不是
p = (atbl + (1 * sizeof(struct a)));
你需要
p = (atbl + 1 );
如果结构atbl
的起始地址是1000
(让我们说),那么将1
添加到它会增加16
单位和p
点到1016
(假设4
为unsigned int
个字节。 p
单位(1
)不会增加1001
此外,您使用错误的说明符来打印地址。这将调用未定义的行为。
如果转换规范无效,行为未定义 .282)如果任何参数不是相应转换规范的正确类型,行为是 未定义即可。
使用%p
说明符打印地址。您的printf
声明应该是:
printf("%8p %8p %8p %8p %8p\n", (void *)p, (void *)atbl, (void *)&atbl[0], (void *)&atbl[1], (void *)&atbl[2]);
建议阅读:Pointer Arithmetic。