以前在学习c语言的时候,有接触过共用体。
彼时对共用体Union的理解无非就是:
union
{
int a;
int b;
char c;
}
对union内的任意成员赋值都会覆盖掉其他成员,当时觉得很好理解,觉得懂了。
但是对于共用体的应用,我一无所知!!!
这是实际工作中接触到的一种共用体的用法,晓得的大佬就别看了,有点丑,感兴趣的可以先看看代码再看下文:
#include
#include
char flash[200];
typedef struct str_test
{
int len;
int size;
int width;
int high;
}str_t;
str_t str=
{
15,
10,
10,
20,
};
typedef union un_test
{
str_t str;
char data[40];
}un_t;
un_t str_union;
str_t * str1=&str_union.str;
void save(void)
{
memcpy(flash,str_union.data,40);
}
void get(void)
{
memcpy(str_union.data,flash,40);
}
void Print(void)
{
printf("%d %d %d %d\r\n",str_union.str.len,
str_union.str.size,str_union.str.width,str_union.str.high);
}
void Print1(void)
{
printf("union*.");
printf("%d %d %d %d\r\n",str1->len,str1->size,str1->
width,
str1->high);
}
void main(void)
{
str_union.str=str;
printf("first: ");
Print1();
save();
printf("second:save to flash\r\n");
memset(str_union.data,0,sizeof(un_t));
str1->len=0;str1->size=0;str1->width=0;str1->high=0;
printf("third:clear str_union.");
Print();
get();
printf("fourth:get data from flash.");
Print();
}
这是程序的打印信息
先说这大概是个什么问题吧。
在对一些用户配置的数据进行存储操作的时候,我们需要把数据存到flash或者eeprom中。
但是怎么存呢?
开始我比较单纯的按字节一个字节放一个字符存进eeprom中,然后进行相应数据解析操作,虽然可行,但是,总感觉太过低端,不符合嵌入式开发节省内存的理念。
于是,老大给了一个共用体的读写eeprom的例子给我自己体会,这是几个相关的数据类型:
typedef struct Settings
{
bool Mode;
bool Dst_flag;
bool Photocell_flag;
bool Schedule_flag;
uint8_t Dim_mode;
int8_t Timezone;
Photocell_t photocell;
Schedule_t schedule;
Dst_t dst;
}Settings_t; //实际需要的结构体数据
typedef union SettingsData {
Settings_t settings;
uint32_t data[sizeof(Settings_t)/4];
} SettingsData_u; //一个成员分别为结构体数据,以及和结构体同样大小的整形的数组。
SettingsData_u SettingsData;//申请一个这样的共用体
Settings_t *Settings = &SettingsData.settings; //申请一个实际需要的结构体指针指向共用体内的结构体成员
然后通过对指针指向的地址的赋值可以对共用体内的结构体赋值。
最重要的Part来了:
我们可以使用共用体的另一个成员,这个数组,直接把数组中的数据放进你想放的地方,比如flash eeprom,anywhere you want put.
然后通过共用体内的这个数组去把你存放的数据取出来,再通过一个结构体指针调出你想用的数据。
具体逻辑就是: union.data[i] -> flash -> union.data[i] -> setting -> real data 。
而前面最开始的那个程序就是我根据实际工程里抽象出来的一个简单的c 语言demo程序。
简单理解一下就是
1 : char flash[200]代替falsh或者eeprom。
2 : save 函数 get 函数分别替代通过共用体内的数组进行的一个存数据 和 取数据的操作。
里面main函数的大概逻辑和流程如下
1: 把事先赋值好的结构体 str 赋值给共用体结构体成员
2:通过申请的指针 str1=&str_union.str打印这个结构体成员的数据
3:把这个共用体通过数组存到那个 flash[200] 的字符数组内
4:清空共用体内两个成员的数据,并打印出清空后的结构体数据
5:通过共用体数组从 flash[200] 中拿回之前存进去的数据,并通过结构体成员打印出来
写在最后的一些疑问
对于共用体的这个用法,我还是有个疑问,那就是既然成员共用的是一个地址空间,为啥子我想直接打印这个数组就打印不出来呀,打印为空,但是我确信里面有数据,因为它有两次换行,搞不明白有点痛苦!!!