gpt4 book ai didi

将结构指针转换为另一个结构

转载 作者:行者123 更新时间:2023-12-02 05:32:32 27 4
gpt4 key购买 nike

此代码片段打印值 5。我不明白为什么。

#include <stdio.h>

struct A
{
int x;
};

struct B
{
struct A a;
int y;
};

void printA(struct A *a)
{
printf("A obj: %d\n", a->x);
}

int main(void)
{
struct B b = {
{
5
},
10
};

struct A *a = (struct A*)&b;
printA(a);

printf("Done.\n");
return 0;
}

当我创建 b 时,指向它的指针将指向数据 { {5}, 10 }

当我将 &b 转换为 struct A* 时,我向编译器保证这个 struct A* 指向一个结构数据类型 int 的单个数据元素。相反,我为它提供了一个指向数据类型为 struct Aint 的两个数据元素的结构的指针。

即使第二个变量被忽略(因为 struct A 只有一个数据成员)我仍然为它提供一个结构,其成员的数据类型为 struct A,不是 int

因此,当我将 a 传递给 printA 时,将执行 a->x 行,本质上是要求访问第一个数据a 的元素。 a 的第一个数据元素是数据类型 struct A,这是一个类型不匹配,因为 %d 需要一个数字,而不是一个结构 A

这里到底发生了什么?

最佳答案

When I create b, a pointer to it would point to the data { {5}, 10 }.

是的,从某种意义上说,它是类型适当且值正确的 C 初始值设定项的文本。该文本本身不应按字面意义作为结构的值。

When I cast &b to struct A*, I'm assuring the compiler that this struct A* points to a struct of a single data element of data type int.

不,不完全是。您正在转换表达式&b 的值以键入struct A *。结果指针是否实际指向 struct A 是一个单独的问题。

Instead, I'm providing it a pointer to a struct of two data elements of data types struct A, int.

不,不是“代替”。鉴于 struct B 的第一个成员是 struct A,并且 C 禁止在结构的第一个成员之前填充,指向 struct B< 的指针 指向一个struct A——一般意义上的B 的第一个成员。正如@EricPostpischi 在评论中观察到的那样,C 标准在您的特定情况下明确指定了结果:给定 struct B b,将指向 b 的指针转换为类型 struct A * 产生一个指向 b 的第一个成员的指针,一个 struct A

Even if the second variable is ignored (since struct A has only one data member) I am still providing it a struct whose member is of data type struct A, not int.

struct B 表示的第一个 sizeof(struct A) 字节构成了它的第一个成员 struct A 的表示.后者是前者的一员,除了内存中的重叠外,没有任何物理表现。

即使语言没有明确指定它,鉴于您将变量 b 声明为 struct B,也没有实际理由期望表达式 (struct A*)&b == &b.a 的计算结果为 false,毫无疑问,右侧指针可用于访问 struct A

Thus, when I pass in a to printA, the line a->x is performed, essentially asking to access the first data element of a.

是的,这就是断言 a 确实指向 struct A 的地方。正如已经讨论过的,它在你的情况下是做什么的。

The first data element of a is of data type struct A,

没有。 *a 根据定义是 struct A。具体来说,它是 struct A,其表示与 b 的表示的开头重叠。如果没有这样的struct A,那么行为将是未定义的,但这不是问题。与每个 struct A 一样,它有一个由 x 指定的成员,即 int

which is a type mismatch due to the %d expecting a digit, not a struct A.

你的意思是期待一个int。这就是它得到的。这就是表达式 a->x 读取的内容,假设行为已定义,因为那是该表达式的类型。在不同的情况下,行为可能确实未定义,但在任何情况下该表达式都不会提供 struct A

What exactly is happening here?

似乎正在发生的事情是,您正在想象与 C 实际提供的不同的、更高级别的语义。特别是,您似乎将结构作为可区分成员对象列表的心理模型,这导致您形成不正确的期望。

也许您更熟悉弱类型语言(如 Perl)或动态类型语言(如 Python),但 C 的工作方式不同。您不能查看 C 对象并有用地问“您的类型是什么”?相反,您通过用于访问它的表达式的静态类型的镜头来查看每个对象。

关于将结构指针转换为另一个结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51757117/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com