C 程序如何访问结构的变量?

C 程序如何访问结构的变量?,c,struct,C,Struct,我正在解决一些与C编程中的结构相关的问题,并遇到以下代码段,正在询问其输出: #include<stdio.h> #include<stdlib.h> #include<assert.h> struct ournode { char x,y,z; }; int main(void) { struct ournode p = {'1','0','a'+2}; struct ournode *q = &p; fprint

我正在解决一些与C编程中的结构相关的问题,并遇到以下代码段,正在询问其输出:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

struct ournode {
    char x,y,z;
};

int main(void) {
    struct ournode p = {'1','0','a'+2};
    struct ournode *q = &p;
    fprintf(stdout,"%c %c\n", *((char*)q+1),*((char*)q+2));
    return 0;
}
回答/输出:0,c

我不能理解

(char*)q+1
指向
char
指针的指针
q
,因此
ournode
的底层内存被视为一个
char
序列;然后
q+1
指向该内存块开始后的下一个
char
,即
'1'

访问这样的变量有什么好处

对于这样一个玩具的例子,这是没有好处的。对于现实世界的例子,它通常仍然是一个围绕糟糕设计的工作,但有时仍然有用。这是一种将同一内存块视为具有多个不同结构的方法,而无需提前声明(例如使用
union
s)。然而,通常情况下,你不应该这样做;它是不安全的,与从头开始正确设计的代码相比,它并不能提供实际的好处


编辑:正如注释中指出的,结构填充可能意味着结构的内存布局不是您天真地期望的,这使得这种技术无法按您期望的方式工作。如果您还不理解它,那么就不值得费心了:)

他们的代码是荒谬的。我只有一个很好的理由可以考虑做他们所做的事情,那就是向后兼容真正的旧系统。早期版本的C不允许->箭头操作符用于取消引用指针。然而,如果他们试图遵守20世纪70年代的标准,那么他们就出了问题


我认为您正在引用的人不理解箭头运算符。

这样做没有任何好处。这不安全,也没有理由这么做。我能看到有人尝试这样做的唯一原因是为了某种多态代码,但这不是正确的方法,没有任何好处。此外,如果成员之间存在填充,结果可能会出人意料。我从地狱中看到的这个构造的唯一好处是,您知道上级的代码审查即将到来,并且您正在寻找一种方便地解雇的方法。一个好处可以是教示结构不是超验的,但它和其他数据类型一样保存在内存中。将结构指针类型转换为数据类型指针是否是一种好的做法,该指针与要提取其值的变量的数据类型相同。例如,这里的代码将结构指针强制转换为char指针,以便从char变量中提取数据。
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

struct ournode {
    char x,y,z;
};

int main(void) {
    struct ournode p = {'1','0','a'+2};
    struct ournode *q = &p;
    fprintf(stdout,"%c %c\n", (q->y),(q->z));
    return 0;
}