我现在的处境是,我拥有一个包含多个元素的匿名结构。为了通过索引访问它们,我将它们放在一个 union 中,如下所示:
union
{
struct
{
unsigned char COMMAND; //STRUCT_ARRAY[0]
unsigned char ADDR_H; //STRUCT_ARRAY[1]
unsigned char ADDR_M; //STRUCT_ARRAY[2]
unsigned char ADDR_L; //STRUCT_ARRAY[3]
unsigned char DATA; //STRUCT_ARRAY[4]
unsigned char CHECKSUM; //STRUCT_ARRAY[5]
};
unsigned char STRUCT_ARRAY[6];
//all of the struct members can be accessed from STRUCT_ARRAY by index
}MY_UNION;
该 union 当前驻留在文件 source.c
中。我需要从 main.c
访问它。我有一个两个文件都包含的 header ,我们将其称为 header.h
。
如何在 main.c 中读取例如 ADDR_H
和 ADDR_M
的值,同时从 source.c 定期修改它?
代码的工作方式有点像这样:
来源.c:
#include "header.h"
union
{
struct
{
unsigned char COMMAND; //STRUCT_ARRAY[0]
unsigned char ADDR_H; //STRUCT_ARRAY[1]
unsigned char ADDR_M; //STRUCT_ARRAY[2]
unsigned char ADDR_L; //STRUCT_ARRAY[3]
unsigned char DATA; //STRUCT_ARRAY[4]
unsigned char CHECKSUM; //STRUCT_ARRAY[5]
};
unsigned char STRUCT_ARRAY[6];
//all of the struct members can be accessed from STRUCT_ARRAY by index
}MY_UNION;
void modify(void)
{
MY_UNION.ADDR_H = somevalue;
MY_UNION.ADDR_M = somevalue;
MY_UNION.ADDR_L = somevalue;
}
在main.c中:
#include "header.h"
void main(void)
{
modify();
print(MY_UNION.ADDR_H); //custom function to print values to a screen
print(MY_UNION.ADDR_M);
print(MY_UNION.ADDR_L);
}
最佳答案
基本程序设计:
- 切勿在头文件中声明变量。
- 切勿使用带有
extern
的意大利式编程。 - 不要直接在处理协议(protocol)的翻译单元之外公开内部结构,例如此协议(protocol)结构。您需要在两者之间有一个抽象层。
快速而肮脏的解决方案:
将 h 文件中的 union 定义更改为 typedef:
typedef union { struct { unsigned char COMMAND; //STRUCT_ARRAY[0] unsigned char ADDR_H; //STRUCT_ARRAY[1] unsigned char ADDR_M; //STRUCT_ARRAY[2] unsigned char ADDR_L; //STRUCT_ARRAY[3] unsigned char DATA; //STRUCT_ARRAY[4] unsigned char CHECKSUM; //STRUCT_ARRAY[5] }; unsigned char STRUCT_ARRAY[6]; //all of the struct members can be accessed from STRUCT_ARRAY by index } MY_UNION;
在 .c 文件中本地声明实际变量:
static MY_UNION my_union;
。使用 setter/getter 访问变量,例如:
uint8_t get_address_h (void) { return my_union.ADDR_H; } void set_address_h (uint8_t addr_h) { my_union.ADDR_H = addr_h; }
正确的解决方案:
在正确的程序中,您应该完全从其他文件中隐藏该协议(protocol)的内部结构,包括 typedef union。
除了协议(protocol)转换器之外,任何人都不应访问此 union 。您将拥有诸如 set_address
、set_data
等调用者无需了解协议(protocol)内部结构即可知道的函数。
关于我可以从 PIC C18 中的 main.c 访问 source.c 中的并集吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53628711/