一文帶你認(rèn)識C語言的聯(lián)合體和枚舉
一.聯(lián)合體
1.聯(lián)合體的聲明
聯(lián)合體(Union) 是一種特殊的用戶自定義數(shù)據(jù)類型,它允許在同一內(nèi)存位置存儲不同類型的數(shù)據(jù),但同時只能存儲其中一個成員。聯(lián)合體的所有成員共享相同的內(nèi)存空間,因此聯(lián)合體的大小等于其最大成員的大小。
我們來看一下簡單定義,有些類似于結(jié)構(gòu)體.。
#include<stdio.h>
union un {
int age;
char i;
};
int main() {
return 0;
}
雖然說結(jié)構(gòu)上有些類似于結(jié)構(gòu)體,但是看特點的話,他兩各不相同,各有所長。
2.聯(lián)合體的特點
(一)內(nèi)存共享
聯(lián)合體的所有成員共享同一塊內(nèi)存地址。意味著不論聯(lián)合體有多少成員,它們都會使用同一個存儲空間。只有一個成員可以在同一時刻存儲有效數(shù)據(jù)。
優(yōu)點:這種特性使聯(lián)合體節(jié)省內(nèi)存,特別適合多個數(shù)據(jù)不會同時使用的場景。
我們來看一個例子:
#include<stdio.h>
union un {
int age;
char i;
};
int main() {
union un u = { 0 };
u.age = 0x11223344;
u.i = 0x55;
return 0;
}
我們按F10進(jìn)入逐過程:
查看內(nèi)存:可以看到u.i的0x55覆蓋了u.age的44
可以說明他們的內(nèi)存是共享的!?。?/strong>


(二)大小等于最大成員的大小
聯(lián)合體的大小等于其最大成員的大小。雖然它可以有多個成員,但只會根據(jù)其中最大成員的大小來分配內(nèi)存。
我們看一下例子:
#include<stdio.h>
union un {
int age;
char i;
};
int main() {
union un u = { 0 };
//計算一下聯(lián)合體的大小
printf("%zd", sizeof(u));
return 0;
}
結(jié)果是:

解釋:int四個字節(jié),char一個字節(jié),顯然最大的是四個字節(jié)。聯(lián)合體的大小即最大成員的大小
另一特殊情況:
當(dāng)最大成員大小不是最大對齊數(shù)的整數(shù)倍的時候,就要對齊到最大對齊數(shù)的整數(shù)倍。
看一例子:
#include<stdio.h>
union un {
char name[10];
int age;
};
int main() {
union un u = { 0 };
printf("%zd", sizeof(u));
return 0;
}
我們看一下結(jié)果:
可以看到聯(lián)合體的大小并不是最大成員的大小10(char1個字節(jié),1*10),是12(最大對齊數(shù)4,4的整數(shù)倍)

這里10個char類型和int類型就已經(jīng)占用14個字節(jié)了,但是結(jié)果是12個字節(jié),所以這里也能證明聯(lián)合體的特點內(nèi)存共享。
(三)一次只能使用一個成員
聯(lián)合體(union)的特性是一次只能有效使用一個成員,因為所有成員共享同一塊內(nèi)存。當(dāng)你向一個成員賦值時,之前賦值的其他成員數(shù)據(jù)會被覆蓋。
其實也就是因為另一個特性內(nèi)存共享導(dǎo)致的
#include <stdio.h>
#include <string.h>
union MyUnion {
int i;
float f;
char str[20];
};
int main() {
union MyUnion u;
// 設(shè)置整數(shù)值
u.i = 42;
printf("設(shè)置整數(shù)后: u.i = %d\n", u.i);
// 設(shè)置浮點數(shù)值,覆蓋整數(shù)值
u.f = 3.14;
printf("設(shè)置浮點型之后: u.f = %.2f\n", u.f);
// 整數(shù)值被覆蓋,無法正常讀取
printf("u.i (設(shè)置浮點型之后) = %d (corrupted)\n", u.i);
// 設(shè)置字符串,覆蓋浮點數(shù)值
strcpy(u.str, "Hello");
printf("設(shè)置字符串后: u.str = %s\n", u.str);
// 浮點數(shù)值被覆蓋,無法正常讀取
printf("u.f (設(shè)置字符串后) = %.2f (corrupted)\n", u.f);
return 0;
}結(jié)果:

3.聯(lián)合體相比較于結(jié)構(gòu)體
(一)內(nèi)存分配
結(jié)構(gòu)體:
- 結(jié)構(gòu)體中的每個成員都有自己獨立的內(nèi)存空間。
- 結(jié)構(gòu)體的總大小等于所有成員大小的總和(加上可能的內(nèi)存對齊)。
- 成員的內(nèi)存布局是順序的,成員之間不會共享內(nèi)存
聯(lián)合體:
- 聯(lián)合體中的所有成員共享同一塊內(nèi)存。
- 聯(lián)合體的總大小等于其中最大成員的大小。
- 只能同時使用一個成員,存入一個成員的值會覆蓋其他成員。
(二)使用方式
結(jié)構(gòu)體:
- 結(jié)構(gòu)體可以同時使用多個成員。每個成員都有獨立的存儲空間,互不干擾。
- 適合用于描述包含多個相關(guān)數(shù)據(jù)的復(fù)雜對象。
(三)內(nèi)存布局對比
看看這兩個代碼內(nèi)存的占用

我們看一下內(nèi)存分布圖:

(四)總結(jié)
| 特性 | 結(jié)構(gòu)體 | 聯(lián)合體 |
| 內(nèi)存分配 | 每個成員都有獨立內(nèi)存,大小為所有成員之和。 | 所有成員共享同一塊內(nèi)存,大小為最大成員。 |
| 使用多個成員 | 可以同時使用多個成員。 | 一次只能使用一個成員,修改會覆蓋其他成員。 |
| 適用場景 | 同時需要存儲和操作多種數(shù)據(jù)類型。 | 不同時間只需使用一種數(shù)據(jù)類型,節(jié)省內(nèi)存。 |
| 訪問速度 | 各成員獨立訪問,互不影響。 | 需要判斷當(dāng)前存儲的成員類型,可能增加復(fù)雜度。 |
二.枚舉
枚舉(enum)是一種用戶自定義的數(shù)據(jù)類型,它由一組具名的常量組成。枚舉常用于表示一組相關(guān)的離散值,賦予這些值易于理解的名稱,增強(qiáng)代碼的可讀性和維護(hù)性。
1.特點
- 命名常量:枚舉為一組常量提供了有意義的名字,使代碼更具可讀性。
- 整數(shù)值:在大多數(shù)編程語言中,枚舉中的每個常量值都與一個整數(shù)值對應(yīng),通常從
0開始遞增,除非顯式指定。- 類型安全:枚舉類型可以幫助確保在代碼中只能使用有效的枚舉常量,而不會混用其他不相關(guān)的值。
2.語法
看個例子:
#include <stdio.h>
enum Weekday {
SUNDAY, // 默認(rèn)值為 0
MONDAY, // 1
TUESDAY, // 2
WEDNESDAY, // 3
THURSDAY, // 4
FRIDAY, // 5
SATURDAY // 6
};
int main() {
enum Weekday today;
today = WEDNESDAY;
if (today == WEDNESDAY) {
printf("Today is Wednesday!\n");
}
return 0;
}
結(jié)果如圖:

第二個例子(如果對某個成員賦值,后續(xù)成員會從該值開始遞增):
enum EnumName {
ENUM_VALUE1, //0
ENUM_VALUE2, //1
ENUM_VALUE3 = 10, // 可以顯式指定值
ENUM_VALUE4 // 之后的值會遞增,即11
};
枚舉中的每個常量值都與一個整數(shù)值對應(yīng),通常從
0開始遞增,除非顯式指定。
ps:要注意每個成員用","隔開
3.特殊情況
(一)枚舉類型的隱式轉(zhuǎn)換
枚舉類型在 C 語言中實際上是整型,可能導(dǎo)致與整型混淆。比如,可以將整型值賦給枚舉類型:
enum Weekday { SUNDAY, MONDAY, TUESDAY };
enum Weekday day = 3; // 這是合法的,但不安全
(二)枚舉的作用域
在 C 語言中,枚舉的常量在枚舉定義的作用域內(nèi)可見,但不會限定在枚舉類型內(nèi)部:
enum Colors { RED, GREEN, BLUE };
int color = RED; // 合法,因為 RED 在全局作用域中可見
(三)缺乏類型安全
盡管枚舉在一定程度上提供了類型安全,但它們的整型本質(zhì)仍然使得在比較或賦值時存在風(fēng)險。例如,可以將一個枚舉類型的變量賦值為與之不相關(guān)的整數(shù)值,這可能導(dǎo)致邏輯錯誤:
enum Direction { NORTH, SOUTH, EAST, WEST };
enum Direction dir = 10; // 合法,但不正確
(四)枚舉的拓展
在 C 語言中,枚舉類型一旦定義就不能被擴(kuò)展或修改。它的值和成員是固定的。因此,枚舉不能如同其他數(shù)據(jù)類型那樣進(jìn)行動態(tài)修改。
總結(jié)
到此這篇關(guān)于C語言聯(lián)合體和枚舉的文章就介紹到這了,更多相關(guān)C語言聯(lián)合體和枚舉內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C語言編程中的聯(lián)合體union入門學(xué)習(xí)教程
- C語言中聯(lián)合體union的實例詳解
- C語言中枚舉與聯(lián)合體的使用方法(enum union)
- C語言結(jié)構(gòu)體,枚舉,聯(lián)合體詳解
- C語言關(guān)于自定義數(shù)據(jù)類型之枚舉和聯(lián)合體詳解
- C語言超詳細(xì)講解結(jié)構(gòu)體與聯(lián)合體的使用
- C語言枚舉與聯(lián)合體深入詳解
- C語言中聯(lián)合體與共用體和枚舉使用語法示例
- c語言中聯(lián)合體和枚舉用法詳解
- C語言聯(lián)合體類型的實現(xiàn)
- C語言聯(lián)合體的實現(xiàn)示例
相關(guān)文章
c++下使用windows api遍歷指定文件夾及其子文件夾中的文件
這篇文章主要介紹了c++下使用windows api遍歷指定文件夾及其子文件夾中的文件實現(xiàn)代碼,一般都是通過c++自帶的函數(shù)實現(xiàn)2021-07-07
C++實現(xiàn)LeetCode(92.倒置鏈表之二)
這篇文章主要介紹了C++實現(xiàn)LeetCode(倒置鏈表之二),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C語言輪轉(zhuǎn)數(shù)組的三種實現(xiàn)
輪轉(zhuǎn)數(shù)組是一種將數(shù)組元素循環(huán)移動的處理方式,它通常用于解決一些需要對固定長度的數(shù)組進(jìn)行循環(huán)滾動處理的問題,本文就介紹了C語言輪轉(zhuǎn)數(shù)組的三種實現(xiàn),感興趣的可以了解一下2023-08-08

