#include <stdio.h>
struct Ournode {
char x, y, z;
};
int main() {
struct Ournode p = {'1', '0', 'a' + 2};
struct Ournode *q = &p;
printf("%c, %c", *((char *)q + 1), *((char *)q + 2));
return 0;
}
我在geeksforgeeks(https://www.geeksforgeeks.org/c-language-2-gq/input-and-output-gq/)上遇到了这个问题(问题21)。 * q如何访问p的元素?如果我们有
这样的结构怎么办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;
}
在这种情况下,我们如何访问元素?有时会根据我创建Ournode的顺序获得垃圾输出(即先创建a,b,c,然后创建x,y,z或x,y,z,然后创建a) ,b,c)。
这里的幕后发生了什么? q如何访问元素?
答案 0 :(得分:4)
method
如何访问*q
的元素?
它通过p
指针执行此操作,使用的规则是char
的地址必须与其初始元素的地址(即字段struct
)匹配。但是,该标准允许编译器在p.x
之后插入填充,因此将x
添加到1
不一定会产生((char*)q)
的地址。
您可以按以下步骤修复程序:
y
由于printf(
"%c, %c"
, *((char *)q + offsetof(struct Ournode, y))
, *((char *)q + offsetof(struct Ournode, z))
);
指向((char*)q)
字段int
的一部分,因此从这些地址打印a
会产生对%c
'部分的实现定义的重新解释表示为int
。就打印char
而言,您应该添加相同的int
技巧来应对潜在的填充结果。
注意::我还没有看到在offsetof
之间插入填充的编译器,但是我没有在标准中找到任何阻止它这样做的东西。如果您使用char
而不是char x, y, z
,则情况会有所不同,因为不允许在数组成员之间进行填充。
答案 1 :(得分:0)
q如何访问元素?
这已经回答了,所以我想回答你的另一个问题。
在这种情况下,我们如何访问元素?有时我会根据创建Ournode的顺序获得垃圾输出(即先创建a,b,c,然后创建x,y,z或先创建x,y,z,然后创建a,b,c)。
如果要通过指向该节点的指针struct Ournode
访问q
的成员,可以使用运算符->
来实现。
您的代码现在将如下所示。
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;
}