以前在學習c語言的時候,有接觸過共用體。
彼時對共用體Union的理解無非就是:
union
{
int a;
int b;
char c;
}
對union內的任意成員賦值都會覆蓋掉其他成員,當時覺得很好理解,覺得懂了。
但是對於共用體的應用,我一無所知!!!
這是實際工作中接觸到的一種共用體的用法,曉得的大佬就別看了,有點醜,感興趣的可以先看看代碼再看下文:
#include <stdio.h>
#include <string.h>
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] 中拿回之前存進去的數據,並通過結構體成員打印出來
寫在最後的一些疑問
對於共用體的這個用法,我還是有個疑問,那就是既然成員共用的是一個地址空間,爲啥子我想直接打印這個數組就打印不出來呀,打印爲空,但是我確信裏面有數據,因爲它有兩次換行,搞不明白有點痛苦!!!