欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言聯(lián)合體的實現(xiàn)示例

 更新時間:2024年11月26日 10:07:44   作者:米飯「」  
C語言聯(lián)合體是一種特殊的數(shù)據(jù)結(jié)構(gòu),它允許在相同的內(nèi)存位置存儲不同的數(shù)據(jù)類型,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、聯(lián)合體類型的聲明

聯(lián)合體也是一種自定義類型。像結(jié)構(gòu)體一樣,聯(lián)合體也是由一個或者多個成員構(gòu)成,這些成員可以是不同的類型。
但是編譯器只為最大的成員分配足夠的內(nèi)存空間。聯(lián)合體的特點是所有成員共用同一塊內(nèi)存空間。所以聯(lián)合體也叫:共用體。聯(lián)合體類型的定義形式:

在這里插入圖片描述

  • union是聯(lián)合體關(guān)鍵字
  • tag是標簽名,是自定義的
  • union tag就是聯(lián)合體類型
  • { }放的是成員列表
  • member1,member2是聯(lián)合體成員
  • variable-list是變量名

來看下面一段代碼:

#include <stdio.h>
//聯(lián)合體類型的聲明
union Un
{
	char c;
	int i;
};
int main()
{
	union Un un = { 0 };//聯(lián)合變量的初始化
	
	printf("%d\n", sizeof(un));//計算聯(lián)合變量的??
	return 0;
}

程序運行結(jié)果:

在這里插入圖片描述

通過計算得到聯(lián)合體變量un的大小為4(單位字節(jié))。為什么是這個值呢?

二、聯(lián)合體的特點

剛剛我們說過聯(lián)合體的所有成員是共用一塊內(nèi)存空間的,這樣一個聯(lián)合體變量的大小,至少是最大成員的大小(因為聯(lián)合體至少得有能力保存最大的那個成員)。我們再來看兩段代碼:

//代碼1
#include <stdio.h>
//聯(lián)合類型的聲明
union Un
{
	char c;
	int i;
};
int main()
{
	//聯(lián)合變量的定義
	union Un un = { 0 };
	//下?輸出的結(jié)果是?樣的嗎?
	printf("%p\n", &(un.i));
	printf("%p\n", &(un.c));
	printf("%p\n", &un);
	return 0;
}

程序運行結(jié)果:

在這里插入圖片描述

//代碼2
#include <stdio.h>
//聯(lián)合類型的聲明
union Un
{
	char c;
	int i;
};
int main()
{
	//聯(lián)合變量的定義
	union Un un = { 0 };
	un.i = 0x11223344;
	un.c = 0x55;
	printf("%x\n", un.i);
	return 0;
}

程序運行結(jié)果:

在這里插入圖片描述

通過代碼1的運行結(jié)果可知,輸出的三個地址一模一樣,而通過代碼2的運行結(jié)果,我們發(fā)現(xiàn)變量i的值變成了0x11223355。我們仔細分析就可以畫出,un的內(nèi)存布局圖。

在這里插入圖片描述

由上圖,這里是小端字節(jié)序存儲,為聯(lián)合變量un的成員i開辟了4個字節(jié)的空間來存儲數(shù)據(jù)0x11223344。而當我們緊接著為該聯(lián)合變量un的成員c賦值0x55時,發(fā)現(xiàn)原來成員i存儲的四個字節(jié)數(shù)據(jù)的低位字節(jié)數(shù)據(jù)的44被修改為了55(這里只修改了i成員的一個字節(jié)數(shù)據(jù),因為成員c是char類型,只占一個字節(jié),所以i只被覆蓋了一個字節(jié))。看到這里應(yīng)該就明白了,那就是聯(lián)合體的成員是共用一塊內(nèi)存空間。對其中一個成員進行賦值修改時,再修改其他成員的值,那原來成員存儲的值就會被剛剛修改的成員值所覆蓋掉。所以對于聯(lián)合體在同一時間最好是只使用一個成員。

上面我們計算過這個聯(lián)合體類型union Un的大小為4,因為這個聯(lián)合體類型有兩個成員:一個是char類型的,一個是int類型的。則要先保證能存儲最大的那個成員,其次小的成員是和這個最大的成員共用同一塊內(nèi)存空間的,所以這里計算出該聯(lián)合體類型的大小就為4。

相同成員的結(jié)構(gòu)體和聯(lián)合體對比

struct S
 {
 char c;
 int i;
 };
 struct S s = {0};

計算該結(jié)構(gòu)體的大小為:

在這里插入圖片描述

union Un
{
	char c;
	int i;
};
union Un un = { 0 };

計算聯(lián)合體的大小為:

在這里插入圖片描述

我們畫出上面的結(jié)構(gòu)體和聯(lián)合體的內(nèi)存布局示意圖進行對比:

在這里插入圖片描述

對于結(jié)構(gòu)體來說,成員c和i是有自己獨立的空間的,而對于聯(lián)合體來說成員c和i是共用同一塊內(nèi)存空間的,這是它們之間的區(qū)別。所以對于結(jié)構(gòu)體和聯(lián)合體來說,它們是有各自的應(yīng)用場景的。

三、聯(lián)合體大小的計算

聯(lián)合體的大小可不是就像上面說的一樣,就是最大成員的大小,不是這么簡單的。那只是其中一條規(guī)則:??● 聯(lián)合的大小至少得是最大成員的大小。??● 聯(lián)合體的大小必須是最大對齊數(shù)的整數(shù)倍。當最大成員的大小不是最大對齊數(shù)的整數(shù)倍的時候,就要對齊到最大對齊數(shù)的整數(shù)倍。

在計算結(jié)構(gòu)體大小時,是有最大對齊數(shù)的,那在計算聯(lián)合體大小時也是有最大對齊數(shù)的。找對齊數(shù)的規(guī)則,跟結(jié)構(gòu)體中是一樣的。上面的第二條規(guī)則是啥意思?我們通過下面的例子來講解:

#include<stdio.h>
union Un1
{
	int i;
	char c;
	short arr1[7];
};
union Un2
{
	char c;
	int i;
	int arr2[3];
};
union Un3
{
	char arr3[5];
	int i;
	double d;
};
int main()
{
	union Un1 un1 = { 0 };
	union Un2 un2 = { 0 };
	union Un3 un3 = { 0 };

	printf("%zd\n", sizeof(un1));
	printf("%zd\n", sizeof(un2));
	printf("%zd\n", sizeof(un3));

	return 0;
}

程序運行結(jié)果:

在這里插入圖片描述

先看第一個聯(lián)合體變量un1,他的成員中最大成員的大小是4,可能會有同學(xué)在有數(shù)組成員的地方犯迷糊,搞不清楚數(shù)組成員到底要怎么計算最大對齊數(shù)?其實很簡單,首先我們知道數(shù)組在內(nèi)存中是連續(xù)存放的,數(shù)組的大小就等于 元素個數(shù)*元素類型的大小。就像這里的聯(lián)合變量un1中數(shù)組成員arr1的大小就是7*sizeof(short)=14(單位字節(jié))。找數(shù)組成員的對齊數(shù),其實就看數(shù)組單個元素類型的大小與編譯器默認對齊數(shù)的較小值即可。所以對于聯(lián)合變量un1的最大對齊數(shù)就為4:

在這里插入圖片描述

那這里最大成員的大小就是14,而14并不是最大對齊數(shù)的整數(shù)倍,所以還要再浪費2個字節(jié),到16就是4的倍數(shù)了,所以聯(lián)合變量un1的大小就為16。

再看第二個聯(lián)合變量un2,該變量三個成員中的最大對齊數(shù)是4,第三個成員數(shù)組arr2的大小為3*sizeof(int)=12,而12正好是最大對齊數(shù)4的倍數(shù),所以該聯(lián)合變量un2的大小就為12。

最后第三個聯(lián)合變量un3,該變量的三個成員中最大對齊數(shù)是8,第一個成員數(shù)組arr3的大小為5*sizeof(char)=5,這里最大的成員就是數(shù)組arr3,但是5不是最大對齊數(shù)8的整數(shù)倍,還要再浪費3個字節(jié),到8就是8的倍數(shù)了。

聯(lián)合體的應(yīng)用案例

使用聯(lián)合體是可以節(jié)省空間的,下面的一個案例可以說明:
比如,我們要搞一個活動,要上線一個禮品兌換單,禮品兌換單中有三種商品:圖書、杯子、襯衫。每一種商品都有:庫存量、價格、商品類型和商品類型相關(guān)的其他信息。

在這里插入圖片描述

如果我們采用結(jié)構(gòu)體的形式來包裝上面的屬性:

struct gift_list
{
	//公共屬性
    int stock_number;//庫存量
    double price; //定價
    int item_type;//商品類型

	//特殊屬性
    char title[20];//書名
    char author[20];//作者
    int num_pages;//?數(shù)
    char design[30];//設(shè)計
    int colors;//顏?
    int sizes;//尺寸
};

上面的結(jié)構(gòu)其實設(shè)計的很簡單,用起來也方便,但是結(jié)構(gòu)的設(shè)計中包含了所有禮品的各種屬性,這樣使得結(jié)構(gòu)體的大小就會偏大(因為結(jié)構(gòu)體中的成員都是有自己獨立的空間的),比較浪費內(nèi)存。因為對于禮品兌換單中的商品來說,只有部分屬性信息是常用的。比如:商品是圖書,那就不需要design、colors、sizes這幾個特殊屬性了。

所以我們就可以把公共屬性單獨寫出來,剩余屬于各種商品本身的屬性用聯(lián)合體包裝起來,這樣就可以減少所需的內(nèi)存空間,一定程度上節(jié)省了內(nèi)存。

struct gift_list
{
    int stock_number;//庫存量
    double price; //定價
    int item_type;//商品類型

    union 
    {
        struct
        {
            char title[20];//書名
            char author[20];//作者
            int num_pages;//?數(shù)  
        }book;
        struct
        {
            char design[30];//設(shè)計
        }mug;
        struct
        {
            char design[30];//設(shè)計
            int colors;//顏?
            int sizes;//尺?            
        }shirt;
    }item;
};

上面的特殊屬性就放在了聯(lián)合體中,因為每創(chuàng)建一個商品變量時,只會用到聯(lián)合體中的其中一個結(jié)構(gòu)體成員,而聯(lián)合體中的成員是共用同一塊內(nèi)存空間的,所以這里大大的節(jié)省了內(nèi)存空間。這就是聯(lián)合體的好處。(上面的結(jié)構(gòu)體中的聯(lián)合體成員及其內(nèi)部的結(jié)構(gòu)體成員都是采用匿名的,意思是這個聯(lián)合變量只會被使用一次)

用聯(lián)合體判斷當前機器是小端還是大端

????聯(lián)合體還可以用來判斷當前自己使用的機器平臺是大端字節(jié)序存儲還是小端字節(jié)序存儲,小端和大端字節(jié)序存儲是什么意思?比如我們創(chuàng)建了一個整型變量 i 存儲了0x00000001這樣一個值,那請問這個值在內(nèi)存中的排放順序是什么?是低位的值開從低地址處開始存放呢,還是低位的值從高地址處開始存放呢?

在這里插入圖片描述

通過使用聯(lián)合體就可以知道當前機器是小端還是大端:

#include<stdio.h>
int check_sys()
{
	union
	{
		int i;
		char c;
	}un;
	un.i = 1;
	return un.c;//返回1是?端,返回0是?端
}
int main()
{
	printf("%d\n", check_sys());
	return 0;
}

程序運行結(jié)果:

在這里插入圖片描述

我們可以逐語句(F11)調(diào)試起來,在內(nèi)存中查看聯(lián)合變量un存儲的值,就是因為在聯(lián)合體中變量i和變量c是共用同一塊內(nèi)存空間的,所以在對整型變量i賦值1后,我們就可以通過字符類型(1個字節(jié))的變量c查看在低位字節(jié)的值是不是1來判斷當前機器是小端還是大端。

在這里插入圖片描述

通過上圖可以看出,我使用的機器平臺采用的是小端字節(jié)序存儲(低位從低地址處開始存放)。

到此這篇關(guān)于C語言聯(lián)合體的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)C語言聯(lián)合體內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++11 線程同步接口std::condition_variable和std::future的簡單使用示例詳解

    C++11 線程同步接口std::condition_variable和std::future的簡單使用示例詳

    本文介紹了std::condition_variable和std::future在C++中的應(yīng)用,用于線程間的同步和異步執(zhí)行,通過示例代碼,展示了如何使用std::condition_variable的wait和notify接口進行線程間同步
    2024-09-09
  • C語言轉(zhuǎn)義字符實例詳解

    C語言轉(zhuǎn)義字符實例詳解

    這里主要介紹了C語言的轉(zhuǎn)義字符的知識,并附有示例代碼,以便理解,希望對學(xué)習(xí) C語言的同學(xué)有所幫助
    2016-07-07
  • C++數(shù)據(jù)結(jié)構(gòu)哈希表詳解

    C++數(shù)據(jù)結(jié)構(gòu)哈希表詳解

    C++標準庫中使用的unordered_map底層實現(xiàn)是哈希表,下面這篇文章主要給大家介紹了關(guān)于C++中使用哈希表(unordered_map)的一些常用操作方法,需要的朋友可以參考下
    2022-07-07
  • 詳解C語言中不同類型的數(shù)據(jù)轉(zhuǎn)換規(guī)則

    詳解C語言中不同類型的數(shù)據(jù)轉(zhuǎn)換規(guī)則

    這篇文章給大家講解不同類型數(shù)據(jù)間的混合運算與類型轉(zhuǎn)換,有自動類型轉(zhuǎn)換和強制類型轉(zhuǎn)換,針對每種轉(zhuǎn)換方法小編給大家介紹的非常詳細,需要的朋友參考下吧
    2021-07-07
  • C++ 約瑟夫環(huán)問題案例詳解

    C++ 約瑟夫環(huán)問題案例詳解

    這篇文章主要介紹了C++ 約瑟夫環(huán)問題案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C++中的volatile關(guān)鍵字及其作用

    C++中的volatile關(guān)鍵字及其作用

    本文介紹了C++中的volatile關(guān)鍵字,它用于標識變量可能被意外修改,以及編譯器不應(yīng)進行優(yōu)化。本文通過具體的代碼示例,闡述了volatile關(guān)鍵字的作用和使用方法,幫助讀者更好地了解該關(guān)鍵字在C++語言中的應(yīng)用場景和實現(xiàn)原理
    2023-04-04
  • C語言中socket相關(guān)網(wǎng)絡(luò)編程函數(shù)小結(jié)

    C語言中socket相關(guān)網(wǎng)絡(luò)編程函數(shù)小結(jié)

    這篇文章主要介紹了C語言中socket相關(guān)網(wǎng)絡(luò)編程函數(shù)小結(jié),是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • C++類常量和類枚舉

    C++類常量和類枚舉

    這篇文章主要介紹了C++類常量和類枚舉,給類當中定義一些常量,可以給所有類的對象使用,比如說我們在類當中定義一個數(shù)組,希望可以定義一個常量,用來初始化數(shù)組的長度,那么下面我i嗎就來看看過程當如何吧
    2022-01-01
  • Qt數(shù)據(jù)庫應(yīng)用之實現(xiàn)通用數(shù)據(jù)生成器

    Qt數(shù)據(jù)庫應(yīng)用之實現(xiàn)通用數(shù)據(jù)生成器

    有兩種應(yīng)用場景需要用到數(shù)據(jù)生成器,一種是需要測試數(shù)據(jù)庫性能,一種是隨機模擬生成一堆數(shù)據(jù),用來測試程序的性能。本文將利用Qt實現(xiàn)通用數(shù)據(jù)生成器,需要的可以參考一下
    2022-02-02
  • Qt利用QDrag實現(xiàn)拖拽拼圖功能詳解

    Qt利用QDrag實現(xiàn)拖拽拼圖功能詳解

    QDrag類為MIME-based拖拽數(shù)據(jù)轉(zhuǎn)換提供支持。本文為大家主要介紹如何利用QDrag類實現(xiàn)拖拽拼圖功能。左邊是打散的圖,拖動到右邊進行復(fù)現(xiàn),此外程序還支持手動拖入原圖片,感興趣的可以了解一下
    2022-07-07

最新評論