【问题标题】:Pointers behaviour in different datatype不同数据类型中的指针行为
【发布时间】:2013-10-25 04:41:54
【问题描述】:
struct check{
unsigned short a;
unsigned short b;
};

static unsigned char v[5] = {1,2,3,4,5};
struct check *p = (struct check *)v;

printf("%d",p->a);
printf("\t%d",p->b);

答案是5131027。我不明白为什么会这样。任何人都可以帮助我理解这个概念。

【问题讨论】:

    标签: c pointers struct


    【解决方案1】:

    这样投射指针不是一个好主意。

    很可能,unsigned short 在你的机器上是 2 个字节,在转换之后,p->a 得到值 0x0201,即十进制 513p->b 得到 0x0403 的值,即是十进制的1027

    请注意,在具有不同字节序的机器上结果会有所不同。例如,在我的机器上,输出是258 (0x0102) 和772 (0x0304)。

    还请注意,您应该使用格式说明符 %u 来打印 unsigned 类型的值:

    printf("%u\t%u\n", p->a, p->b);
    

    【讨论】:

    • @GrijeshChauhan 很好,我会对此添加注释。
    【解决方案2】:

    更新

    这似乎正在发生...字符数组在内存中的布局如下:

    v+0: 0x01
    v+1: 0x02
    v+2: 0x03
    v+3: 0x04
    v+4: 0x05
    

    当您将 v 转换为 struct check * 类型并取消引用它时,此内存区域将被重新解释如下:

    p->a: 0x0201 (v+1, v+0)
    p->b: 0x0403 (v+3, v+2)
    

    0x0201 十六进制等于 513,0x0403 等于 1027。

    其他想法...

    请务必注意,您无法对代码的行为做出任何保证。对于初学者来说,取消引用 p 是一种严格的别名违规。请参阅 What is the strict aliasing rule? 以了解有关严格别名规则的说明以及影响此类代码的其他因素的列表。

    【讨论】:

    • 实际上,您无法保证此代码的行为,因为取消引用 p 构成严格的别名违规。
    • @tab 谢谢...我已更新我的答案以反映您的评论。
    猜你喜欢
    • 1970-01-01
    • 2012-09-13
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多