C语言结构访问元素
在这种情况下,我们如何访问元素?我有时会根据创建节点的顺序(即a、b、c先创建x、y、z或x、y、z先创建a、b、c)获得垃圾输出 这里的幕后发生了什么?q是如何访问元素的C语言结构访问元素,c,C,在这种情况下,我们如何访问元素?我有时会根据创建节点的顺序(即a、b、c先创建x、y、z或x、y、z先创建a、b、c)获得垃圾输出 这里的幕后发生了什么?q是如何访问元素的 *q如何访问p的元素 它是通过char指针来实现的,使用的规则是struct的地址必须与其初始元素的地址匹配(即fieldp.x)。但是,该标准允许编译器在x之后插入填充,因此将1添加到((char*)q)不一定会产生y的地址 您可以按如下方式修复程序: struct Ournode { int a,b,c; cha
*q
如何访问p
的元素
它是通过char
指针来实现的,使用的规则是struct
的地址必须与其初始元素的地址匹配(即fieldp.x
)。但是,该标准允许编译器在x
之后插入填充,因此将1
添加到((char*)q)
不一定会产生y
的地址
您可以按如下方式修复程序:
struct Ournode {
int a,b,c;
char x, y, z;
int d;
};
int main() {
struct Ournode p = {3,4,5,'1', '0', 'a' + 2,6};
struct Ournode *q = &p;
printf("%c, %c", *((char *)q + 1), *((char *)q + 2));
printf("%d, %d\n", *((int *)q + 1), *((int *)q +2 ));
return 0;
}
由于((char*)q)
指向int
字段a
的一部分,因此从这些地址打印%c
会产生对int
表示为char
的部分的实现定义的重新解释。就打印int
s而言,您应该为技巧添加相同的偏移量,以抵消潜在填充的结果
注意:我还没有看到在char
s之间插入填充的编译器,但是我在标准中没有找到任何东西阻止它这样做。如果使用char x[3]
而不是char x,y,z
,情况会有所不同,因为数组成员之间不允许填充
q是如何访问元素的
这已经得到了回答,所以我想回答你的另一个问题
在这种情况下,我们如何访问元素?有时,根据创建节点的顺序(即a、b、c先创建x、y、z或x、y、z先创建a、b、c),我会获得垃圾输出
如果您想通过指向该节点的指针q
访问struct Ournode
的成员,则有一个操作符->
可以实现这一点。
您的代码现在将如下所示
printf(
"%c, %c"
, *((char *)q + offsetof(struct Ournode, y))
, *((char *)q + offsetof(struct Ournode, z))
);
仅供参考,您可以将q
的类型更改为void*
,并具有相同的输出和可能的问题。所有这些类型转换都很重要,与您看到的输出相关,并且基本上忽略了q
的指针类型,从而使其不相关。你应该更多地了解铸造的作用(然后避免使用它们,因为它们通常意味着你在做一些有问题的事情,特别是对于初学者)。
printf(
"%c, %c"
, *((char *)q + offsetof(struct Ournode, y))
, *((char *)q + offsetof(struct Ournode, z))
);
int main() {
struct Ournode p = {3,4,5,'1', '0', 'a' + 2,6};
struct Ournode *q = &p;
printf("%d, %d, %d, %c, %c, %c, %d", , q->a, q->b, q->c, q->x, q->y, q->z, q->d );
return 0;
}