【问题标题】:Are struct names pointers to first element?结构名称是指向第一个元素的指针吗?
【发布时间】:2015-09-15 23:43:37
【问题描述】:

我发现了一些类似的问题,但都没有太大帮助。结构名称是否指向结构的第一个元素,类似于数组?

struct example {
    int foo;
    int bar;
};

struct example e;
e.foo = 5;
e.bar = 10;
printf("%d\n%d\n%d\n%d\n%d\n%d\n", e, e.foo, e.bar, &e, &e.foo, &e.bar);

输出:

5
5
10
2033501712
2033501712
2033501716

其他问题的所有答案都说“不”,但这个输出让我感到困惑。所有帮助将不胜感激。

【问题讨论】:

    标签: c pointers struct


    【解决方案1】:

    struct 的地址确实是第一个元素的地址,但您需要知道元素的类型才能安全地转换它。

    (C17 §6.7.2.1.15: "一个指向结构对象的指针,适当地 转换后,指向其初始成员……反之亦然。也许有 作为结构对象内的未命名填充,但不在其 开始。”)

    虽然它有点难看,但许多生产软件都依赖于此。例如,QNX 在编写资源管理器时在开放控制块 (OCB) 逻辑中使用这种行为。 Gtk 也有类似的东西。

    不过,您当前的实现很危险。如果您必须依赖此行为,请这样做,并且不要尝试将指向结构的指针作为参数传递给 printf(),因为您故意破坏了具有最小类型安全性的语言的功能.

    struct example {
        int foo;
        int bar;
    };
    
    struct example myStruct = { 1, 2 };
    int* pFoo = (int*)&myStruct;
    printf("%d", *pFoo);
    

    最后,这只适用于第一个元素。后续元素可能与您期望的情况不同,namely due to struct packing and padding

    【讨论】:

    • 您应该在第一句话中更改“指向”一词,否则某些人可能会否决您的答案而被遗忘。
    • 有趣的是,这可能如何适用于您无法指向的成员。 (例如一个位域)
    【解决方案2】:

    struct 名称不是指向任何东西的指针。您通过将带有不兼容格式说明符 %dstruct 传递给 printf 来调用 未定义的行为。它可能看起来“有效”,因为结构的第一个成员与 struct 本身具有相同的地址。

    【讨论】:

    • 我根本不知道它是如何“工作”的,结构的大小与 int“应该”的大小不同导致所有其他输出都出现乱码
    • @MM UB?也许参数是在 OP 的平台上向后读取的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-04
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多