色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

關鍵字union的基本定義和使用

CHANBAEK ? 來源:明解嵌入式 ? 作者:Sharemaker001 ? 2023-04-15 11:18 ? 次閱讀

關鍵字union,又稱為聯合體、共用體,聯合體的聲明和結構體類似,但是它的行為方式又和結構體不同,這里的行為方式主要指的是其在內存中的體現,結構體中的成員每一個占據不同的內存空間,而聯合體中的所有成員共用的是內存中相同的位置。

簡單看下區別:

struct MyStruct 
{
    double a;
    int b;
    char c;
};
struct MyStruct value;
union MyUnion 
{
    double a;
    int b;
    char c;
};
union MyUnion value;

同樣是定義變量value; 內存空間占用情況如下:

圖片

可以看出,結構體變量中3個成員相當于3個人,每個人必須要住一間屋子,優點是空間包容性強,但是內存空間必須全部分配,不管房子住不住人。 聯合體變量3個成員,它們可以共用一間屋子,但是每個屋子同一時間只能容納一個成員,因此不夠包容,成員是互斥的,但是可以大大節省內存空間。

要注意的是,聯合體的長度大小為最大的成員的大小,在本例中即value.a的大小。 并不是單指數據類型,若在MyUnion定義了數組char c[10],則此時該聯合體變量value大小為10個字節。

以上簡單的了解了下union的基本定義,在實際應用中我們一般都使用結構體來定義數據組合而成的結構型變量,而在各數據類型各變量占用空間差不多并且對各變量同時使用要求不高的場合(單從內存使用上)也可以靈活的使用union。

1、變量的初始化

在初始化的時候,只應對一個成員進行初始化即在初始化列表中只有一個初始值。 原因就是聯合體的所有成員共用一個首地址,在默認情況下,會將這個初始值初始化給聯合體變量的第一個成員。

union MyUnion 
{
    double a;
    int b;
    char c;
};
//為第一個成員初始化
union MyUnion un1 = {5.0f};
//錯誤初始化,不能為多個成員初始化
union MyUnion un1 = {5.0f, 10};
//對其它位置的成員進行初始化,則可以通過指定初始化方式
union MyUnion un1 = {.b = 10};
//結構體一樣,也可以將一個聯合體變量作為初始值,直接初始化給同類型的另一個聯合體變量
union MyUnion un2 = un1;

2、數據位操作

#include
typedef struct
{
  unsigned char bit0:1;
  unsigned char bit1:1;
  unsigned char bit2:1;
  unsigned char bit3:1;
  unsigned char bit4:1;
  unsigned char bit5:1;
  unsigned char bit6:1;
  unsigned char bit7:1;
}bitValue;
typedef union
{
  unsigned char bytedata;
  bitValue  bitdata; 
}regValue;
int main()
{
  regValue data;
  data.bytedata= 0x5A;
  printf("%d",data.bitdata.bit5);  //讀取第6位
  data.bitdata.bit7 = 1;           //修改第8位
  return 0;
}

可以看出,通過訪問和修改聯合體中的定義bitdata成員,可以間接的訪問和修改定義的bytedata的值,這可以用在嵌入式寄存器位操作上。

3、和struct嵌套使用

比如我們分別定義電視和空調的屬性:

struct tvFeature    //電視屬性
{
   char *logo;     //品牌
   int price;      //價格
   int screensize  //屏幕尺寸  
   int resolution  //分辨率 
}tvFeature;
struct tvFeature tvfeature;


struct airFeature  //空調屬性
{
   char *logo; //品牌
   int price;   //價格
   int coldcapacity;//制冷量 
   int hotcapacity;//制熱量
}airFeature;
struct airFeature airfeature;

可以看出電視和空調有相同的屬性,也有各自特有的屬性。 我們可以使用家用電器的數據結構統一定義。 但是這樣用統一的數據結構定義電視和空調的變量之間耦合會增加很多,對于tvfeature和airfatureta各自來說用不到的屬性也會浪費內存空間。

struct homeappliancesFeature  //電器屬性
{
   char *logo; //品牌
   int price;   //價格
   int screensize  //屏幕尺寸  
   int resolution  //分辨率
   int coldcapacity;//制冷量 
   int hotcapacity;//制熱量
}homeappliancesFeature;


struct homeappliancesFeature tvfeature;
struct homeappliancesFeature airfature;

因此可以用union來解決問題

struct tvFeature    //電視屬性
{
   int screensize  //屏幕尺寸  
   int resolution  //分辨率 
}tvFeature;
struct airFeature  //空調屬性
{
   int coldcapacity;//制冷量 
   int hotcapacity;//制熱量
}airFeature;


struct homeappliancesFeature  //電器屬性
{
   char *logo; //品牌
   long country; //國家
   union
   {
      struct tvFeature tvST;
      struct airFeature airST;
   };
};
struct homeappliancesFeature tvfeature;
struct homeappliancesFeature airfature;

如上我們只需一個結構體,就可以解決電視和空調的屬性不同問題; struct tvFeature tvST和struct airFeature airST共用一塊內存空間,定義變量時,可以訪問各自的特有屬性,這樣就解決了內存浪費和變量耦合高的問題。

4、數據復制

例如串口數據發送時,可以直接使用數據復制的方式將數據打包發送,不需要將一個4字節的數據額外進行拆分為4個單字節的數據; 反之讀取數據時,也可以不用將4個單字節的數據重新通過移位拼接為一個4字節數據。

typedef union
{
  uint8   data8[4];
  uint32  data32;
}dataType;


uint32 sendData = 0x5A5AA5A5;
uint32 receiveData;
dataType commSend;
void main(void)
{
    uint8 commData[128];     
    //數據復制
    commData.data32 = sendData;    
    //發送數據,字節復制,不需要再將commData.data32單獨移位拆分
    commData[0]= commSend.data8[0];
    commData[1]= commSend.data8[1];
    commData[2]= commSend.data8[2];
    commData[3]= commSend.data8[3];
      
   //讀取數據時,字節復制,不需要再將已經讀取到的4個單字節數據拼接 
   receiveData =  commData.data32;  
}

5、分時發送不同幀格式數據

比如需要在同一段通信數據發送邏輯中,針對不同通信協議幀格式進行發送時,就可以這樣定義數據結構。

typedef struct 
{ 
   uint8 head;   //幀頭格式相同
   union    //中間數據格式不一樣
   {
      struct             //payloadType1  
      {
        uint8 cmd;
        uint8 type;
        uint8 data[5];   
        uint8 check;       
      }msgType1;
   
      struct              //payloadType2    
      {
        uint16 cmd;     
        uint8 data[8];   
        uint16 check;       
      }msgType2;  
          
     uint8 data[10];      //payloadType3  
   } payloadType;
   uint8 end;    //幀尾格式相同
}frameType;

By the way:在使用聯合體時可以注意這兩個點:

1、數據大小端

使用聯合體時需要注意數據大小端問題,這個取決于實際的處理器的存儲方式。

大端存儲就是高字節數據放在低地址。

小端存儲就是高字節數據放在高地址.

如下方例子,可以知道使用的處理器的存儲方式:

#include
union Un
{
  int i;
  char c;
};
union Un un;
int main()
{
  un.i = 0x11223344;
  if (un.c == 0x11)
  {
    printf("大端\\n");
  }
  else if (un.c == 0x44)
  {
    printf("小端\\n");
  }  
}

2、指針方式訪問

由于在一個成員長度不同的聯合體里,分配給聯合體的內存大小取決于它的最大成員的大小。 如果內部成員的大小相差太大,當存儲長度較短的成員時,浪費的空間是相當可觀的,在這種情況下,更好的方法是在聯合體中存儲指向不同成員的指針而不是直接存儲成員本身。 所有指針的長度都是相同的,這樣能解決內存空間浪費的問題。

#include
typedef struct
{
  unsigned char a;
  int b;
}stValue1;
typedef struct
{
  int c;
  unsigned char d[10];
  double e;
}stValue2;
//聯合體成員定義為指針成員
union Un
{
  stValue1 *ptrSt1;
  stValue2 *ptrSt2;
};
int main()
{
  union Un *info;
  info->ptrSt1->a = 5;
  info->ptrSt2->e = 9.7f;
}

總之在實際使用聯合體union過程中一句話總結:圍繞成員互斥和內存共享這兩個核心點去靈活設計你的數據結構。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5085

    文章

    19138

    瀏覽量

    305689
  • 內存
    +關注

    關注

    8

    文章

    3028

    瀏覽量

    74098
  • 關鍵字
    +關注

    關注

    0

    文章

    37

    瀏覽量

    6908
  • 結構體
    +關注

    關注

    1

    文章

    130

    瀏覽量

    10848
  • union
    +關注

    關注

    0

    文章

    10

    瀏覽量

    4285
收藏 人收藏

    評論

    相關推薦

    在NVM和本地\"內存中定義數組(靜態 /global /local)的\"關鍵字是什么?

    在 NVM 和本地\"內存中定義數組(靜態 /global /local)的\"關鍵字是什么? 還有與 32 位對齊的關鍵字怎么樣。
    發表于 01-25 07:52

    DSP編程技巧之17---非常“關鍵”的關鍵字

    的設計產生預期的結果。C28x的編譯器支 持所有的標準C89的關鍵字,包括const、volatile和register,標準的C99關鍵字,包括inline和restrict,以及支持 TI自定義的擴展
    發表于 08-20 11:38

    static 關鍵字

    static 關鍵字 淺析
    發表于 01-16 16:55

    volatile關鍵字應用場景及示例

    volatile關鍵字1.應用場景2.示例1.應用場景volatile關鍵字分析,往往應用在三種場合1)多線程編程共享全局變量的時候,該全局變量要加上volatile進行修飾,讓編譯器不要優化該變量
    發表于 08-24 07:21

    關鍵字static的作用是什么

    嵌入式面經1.關鍵字static的作用是什么2.關鍵字const是什么含意?3.const和宏定義的區別4.關鍵字volatile有什么含意 并給出三個不同的例子。5.引用和指針有什么
    發表于 11-09 07:23

    arduino關鍵字資料

    arduino關鍵字
    發表于 04-23 10:46 ?7次下載

    java中static關鍵字的作用

    static關鍵字是很多朋友在編寫代碼和閱讀代碼時碰到的比較難以理解的一個關鍵字,也是各大公司的面試官喜歡在面試時問到的知識點之一。下面就先講述一下static關鍵字的用法和平常容易誤解的地方,最后
    發表于 09-27 17:12 ?0次下載

    Keil自定義關鍵字、 快捷鍵···

    Keil自定義關鍵字、快捷鍵···
    的頭像 發表于 03-12 11:33 ?5118次閱讀

    C語言:結構體、聯合體嵌套使用的實用操作

    ? 結構體、聯合體是C語言中的構造類型,結構體我們平時應該都用得很多。但是,對于聯合體,一些初學的朋友可能用得并不多,甚至感到陌生。我們先簡單看一下聯合體: 在C語言中定義聯合體的關鍵字union
    的頭像 發表于 12-24 16:07 ?5504次閱讀
    C語言:結構體、聯合體嵌套使用的實用操作

    基于關鍵字的自定義古詩句生成設計與實現

    Seq2Seq模型,通過自建的數據集進行訓練,實現了基于關鍵字的自定乂古詩句生成。在生成階段,首先輸入一段描述性內容,并從中提取岀關鍵字。當關鍵字不足時,使用word2vec進行有效的關鍵字
    發表于 04-12 15:30 ?20次下載
    基于<b class='flag-5'>關鍵字</b>的自<b class='flag-5'>定義</b>古詩句生成設計與實現

    python語言之使用async關鍵字定義函數

    早期的協程是用yield來實現的,但是代碼特別難懂, python3.5之后的版本, 使用 async 關鍵字定義的函數。調用該函數,會返回一個協程對象
    的頭像 發表于 08-24 11:12 ?2750次閱讀

    ARM中關鍵字的具體使用

    奇怪。之前對于 __weak 關鍵字一直是一個簡單的認知:「編譯器自動使用沒有 __weak 的同名函數(如果有的話)替換有 __weak 關鍵字的同名函數,__weak 函數可以沒有定義,且編譯器
    的頭像 發表于 02-10 15:06 ?1282次閱讀

    const關鍵字應用總結

    C++中的const關鍵字的用法非常靈活,而使用const將大大改善程序的健壯性
    的頭像 發表于 05-26 09:06 ?577次閱讀

    LL庫中常見關鍵字__STATIC_INLINE

    LL庫中常見關鍵字__STATIC_INLINE,其定義見cmsis_gcc.h
    的頭像 發表于 07-24 11:30 ?1464次閱讀
    LL庫中常見<b class='flag-5'>關鍵字</b>__STATIC_INLINE

    快速掌握C語言關鍵字

    C語言中的32個關鍵字你知道多少個呢?根據關鍵字的作用分為四類:數據類型關鍵字、控制語句關鍵字、存儲類型關鍵字和其它
    的頭像 發表于 07-06 08:04 ?358次閱讀
    快速掌握C語言<b class='flag-5'>關鍵字</b>
    主站蜘蛛池模板: 里番※琉璃全彩acg奈亚子| 色偷偷7777www| 亚洲中文字幕国产综合| 挤奶门事件完整照片| 综合精品欧美日韩国产在线| 嫩交18xxxx| 国产精品视频在线自在线| 一本道色播| 欧式午夜理伦三级在线观看| 国产黄a三级三级三级| 伊人久久伊人| 破女在线观看视频| 国产又湿又黄又硬又刺激视频 | 三级黄色小视频| 黄片在线观看| wwwzzz日本| 亚洲综合中文字幕无线码| 漂亮的保姆3中文版完整版 | 美女露出逼| 国产午夜三级一区二区三| 最新中文字幕在线视频| 无码AV熟妇素人内射V在线| 狼与美女谐音歌词| 国产精品爽黄69天堂A片| 97se se| 亚洲国产综合久久久无码色伦| 男人被绑着强行摸j| 国内精品视频在线播放一区| www免费看.男人的天堂| 一边吃奶一边啪啪真舒服| 日本中文一区| 美女挑战50厘米长的黑人| 国产亚洲精品AV麻豆狂野| jk制服喷水| 综合激情区视频一区视频二区| 先锋影音 av| 日本无修肉动漫在线观看| 妹妹我要色| 久久久久久极精品久久久| 国产精品久久一区二区三区蜜桃 | 男人边吃奶边摸边做刺激情话|