我希望看到 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 %08xn", p, atbl, &atbl[0], &atbl[1], &atbl[2]);
但我得到以下结果:
P - DAE83240
ATBL - DAE83140
&atbl[0] - DAE83140
&atbl[1]- DAE83150
&ATBL[2] - DAE83160
任何提示?
// read address of element 1 in atbl
p = (atbl + (2 * sizeof(struct a)));
这应该是:
p = atbl + 1;
将 1 添加到已指向第一个条目的内容将使其指向第二个条目。因此,添加两个将使其指向第三个条目。您希望它指向第二个条目,因此您需要添加一个条目。
此外,您不会乘以大小,因为指针已经知道它指向的事物的大小。添加一个对象已经使它指向下一个对象。
指针算术会自动考虑指向对象的大小;你不需要乘以sizeof(struct a)
。
atbl
,在隐式数组到指针转换之后,是类型为 struct a*
的指针。 atbl + 2
点 2 struct a
元素超过atbl
指向的地址。
此外,不要使用 %x
打印指针值;而是将指针值强制转换为 void*
并使用 %p
。
而不是
p = (atbl + (1 * sizeof(struct a)));
你需要
p = (atbl + 1 );
如果结构atbl
的起始地址是1000
(假设),则向其添加1
会将其增加16
个单位,并将p
指向1016
(假设unsigned int
4
字节)。它不会按1
单位递增p
( 1001
)此外,您使用了错误的说明符来打印地址。这将调用未定义的行为。
C11: 7.21.6 格式化输入/输出函数:
如果转换规范无效,则行为未定义。282)如果任何参数不是相应转换规范的正确类型,则行为为 未定义。
使用%p
说明符打印地址。您的printf
语句应如下所示:
printf("%8p %8p %8p %8p %8pn", (void *)p, (void *)atbl, (void *)&atbl[0], (void *)&atbl[1], (void *)&atbl[2]);
推荐阅读:指针算术。