Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-结构和用户变量共享相同的内存-可能吗?_C_Pointers_Struct - Fatal编程技术网

C-结构和用户变量共享相同的内存-可能吗?

C-结构和用户变量共享相同的内存-可能吗?,c,pointers,struct,C,Pointers,Struct,对不起,C中的新手问题。我有以下问题 假设我有一个结构: struct foo { char var_a; char var_b; char var_c; }; 以及变量列表: foo j; char a, b, c; 我想确定,在所有时刻,j.var_a等于a,j.var_b等于b,j.var_c等于c。例如,我希望结构成员也可以像普通用户变量一样随时访问。我认为结构成员只需要与已定义的用户变量共享相同的内存位置,因此假设必须将其中的某些内容定义为指针,并尝试以下操

对不起,C中的新手问题。我有以下问题

假设我有一个结构:

struct foo {
   char  var_a;
   char  var_b;
   char  var_c;
};
以及变量列表:

foo j;
char a, b, c;
我想确定,在所有时刻,j.var_a等于a,j.var_b等于b,j.var_c等于c。例如,我希望结构成员也可以像普通用户变量一样随时访问。我认为结构成员只需要与已定义的用户变量共享相同的内存位置,因此假设必须将其中的某些内容定义为指针,并尝试以下操作:

foo *j;
char a, b, c;
在main()函数中:

j = &a;
目的是将结构指针的地址分配给a的地址,并假设a、b、c将位于相邻的内存空间中。但编译器显然会抛出错误,因为我无法将一种类型的指针指向另一种类型的地址。我也觉得这是不安全的,因为它与内存中变量的顺序有关


那么,是否有一种安全的方法来实现这一目标,而无需在每次更改任何变量和复制额外内存时手动重新分配?我有一个嵌入式目标,因此希望节省内存和处理器时间。

你是正确的,因为你给出的原因,
j=&a
不会做你期望的事情

您可以将
struct foo
的成员定义为指针:

struct foo {
   char  *var_a;
   char  *var_b;
   char  *var_c;
};

char a, b, c;
foo j = { &a, &b, &c };

字符a、b、c局部变量不能保证是连续的、有序的,也不能保证在内存中退出

没有办法在它们上面牢固地覆盖一个结构

假装某些局部变量覆盖结构可以做的事情是使这些“局部变量化”宏:


尽管在某些情况下,能够使用“普通变量”语法访问结构的成员是有用的(除其他外,它可以提高性能,允许将保存/恢复程序状态的代码简化为单个结构的写/读等)最接近C的是允许使用
#define
宏将“变量”名称替换为对结构的引用

比如说,

struct foo { int foo_woozle, foo_moozle; } myFoo;
#define woozle myFoo.foo_woozle
#define moozle myFoo.foo_moozle
不幸的是,这种方法要求“变量”名称在编译单元内的任何其他上下文中都不作为标记出现。例如,如果试图声明一个名为
woozle
的成员的结构,则结构声明将失败,因为其名称将被替换为
myFoo.foo\u woozle

在某些实现中,可以执行以下操作:

extern int woozle,boozle;
extern volatile struct foo myFoo;

然后使用另一种语言(如汇编)编写的代码根据需要覆盖对象。不幸的是,除非禁用优化或对象都是限定的
volatile
,否则这可能是不可靠的。因此,使用
#define
的方法将能够生成更高效的代码,但不幸的是,宏替换带来了难看的语义限制。

感谢您的快速回答。但问题是,我真的需要通过
j.var_a
等访问
struct foo
成员,遗留代码也是如此,我无法更改。@syoma那么你就不走运了。有些事情需要改变。谢谢。我会试试你的建议。让你知道这些变量是全局的。@syoma如果它们是全局的并且是可见的,那么你的目标实际上可以通过一些非标准的链接器技巧来实现。也许这是一个要点。事实上,为了让情况更清楚-这就是如何在两个不同的.c文件中定义这些变量,我必须以某种方式将它们链接在一起,最好不用额外的计算代码。事实上,我没有像你和@PSkocik建议的那样考虑定义。我试试这个。谢谢关于这件事的一些愚蠢的问题——有可能用另一种方式解决吗?A.g.woozle和moozle被声明为实变量,但myfoo.foo_woozle将被混淆?@syoma:这是不可能的,除非结构名称和所有成员名称专门用于这些目的。人们可以做一些可怕的事情,比如用
替换
myfoo
((0*sizeof somestruct
foo\u-woozle
替换
somemember)[&woozle])
,这样
myfoo.foo\u-woozle
就会变成
((0*sizeof somestruct.somemember)[&woozle])
,但在这种情况下,几乎可以肯定,用
myfoo.
替换
myfoo.
会更容易。
extern int woozle,boozle;
extern volatile struct foo myFoo;