如何系統學習C 語言(中)之 聯合體、列舉篇

Charmchin發表於2021-11-12

在C語言中有一個和結構體非常像的資料型別,它的名字叫做聯合體,也被稱為共用體或公用體。

1,聯合體

1,聯合體的定義

定義聯合體需要使用"union" 關鍵字,格式如下:

union 聯合體名{
	資料型別 成員1;
	資料型別 成員2;
	...
};

2,聯合體的大小

聯合體和結構體最大的區別就是在記憶體儲存上。結構體的每個成員都有自己獨立的記憶體空間,結構體大小為所有成員的大小之和(不考慮記憶體對齊情況)。而聯合體的所有成員都使用同一段記憶體空間,聯合體的大小即為聯合體中最大的那個成員大小。例如定義下面一個聯合體:

union A {
	char a;
	int b;
	double c;
};

最大的成員是double 型別的 c ,大小為8個位元組。因此聯合體的大小就是c 的大小。同樣,我們也可以用 sizeof運算子來獲取聯合體A 的大小。

3,聯合體變數的初始化

因為聯合體不能同時儲存多個成員的值。所以,在初始化的時候,只應對一個成員進行初始化,即初始化列表中只放一個初始值。在預設情況下,會將這個初始值給聯合體變數的第一個成員。例如:

union A a1 = {'A'};

如果想對其他位置的成員進行初始化,則可以通過指定初始化方式。例如:

union A a1 = {.b=35};	//通過指定初始化將聯合體變數a1的成員b初始化值為35

4,聯合體變數的訪問和賦值

對聯合體變數中的成員賦值,也是使用成員訪問運算子,即點運算子。如下:

union A a1 = {'A'};
printf("Member a : %c\n",a1.a);	//輸出結果為 Member a :A

聯合體應用案例

在計算機網路中,兩臺計算機要想通訊,就需要知道彼此的ip 地址。那我們思考一下如何儲存類似於“192.168.0.1”的點分格式的ip 地址呢?

下面我們就編寫程式,由使用者輸入一個ip地址,程式可以將其轉換為4 位元組整型型別的IP 地址值,並列印輸出:程式碼如下:

#include<stdio.h>
union IP{
	unsigned char str[4];
	unsigned int digit;
};

int main(){
	union IP ip;	//定義聯合體變數ip
	printf("Please enter IP address in string format:\n");
	//接收使用者輸入的IP地址,並將其儲存至字元陣列
	scanf("%d.%d.%d.%d",&ip.str[0],&ip.str[1],&ip.str[2],&ip.str[3]);
	//列印輸出數字格式的IP地址值
	printf("IP address in digital format is: %u\n",ip.digit);
	return 0;
}

2,列舉

C語言中,還允許定義列舉型別。使用列舉型別,可以提高程式程式碼的健壯性和可讀性,並且列舉成員屬於常量

1,列舉的定義

列舉的定義格式為:

enum 列舉名{列舉成員1,列舉成員2,...};

例如定義一個和方向相關的列舉型別Dir:

enum Dir{up,down,left,right};

前面說了,列舉成員是常量,既然是常量,就應該有對應的值,那上面的四個方位的值又是多少呢?那下面就讓輸出語句告訴我們吧:

printf("up = %d\n",up);
printf("down = %d\n",down);
printf("left = %d\n",left);
printf("right = %d\n",right);
//執行結果如下:
up = 0;
down =1;
left = 2;
right =3;

是否發現了什麼呢?是的,預設情況下,列舉成員是一個整型值,其第一個列舉成員的值為0,而後續列舉成員的值為其前一個列舉成員的值加1。

那是否能夠自己設定列舉成員的值呢?當然是可以的。例如:

enum Dir{up,down = 10,left,right};
//同樣通過printf 語句輸出結果就是你想的那樣:
up = 0;
down = 10;
left =11;
right =12;

2,列舉變數的定義

列舉變數的定義與結構體和聯合體的變數定義方式類似,如通過如下幾種方式:

enum Dir dir1;	//先定義列舉,再定義列舉變數
enum Dir{up=2,down,left,right}dir2;	//在定義列舉的同時定義列舉變數
enum {up=2,down,left,right}dir3;	//定義無名列舉型別的列舉變數

最後,C 語言中,可以將列舉成員視為整型常量,而將列舉變數視為整型變數。因此,可以將一個整型值初始化或者賦值給列舉變數。

相關文章