1. 程式人生 > >【掃盲點】——C語言enum列舉型別、union共用體

【掃盲點】——C語言enum列舉型別、union共用體


一、列舉型別  enum:

在實際應用中,有的變數只有幾種可能取值。如人的性別只有兩種可能取值,星期只有七種可能取值。在 C 語言中對這樣取值比較特殊的變數可以定義為列舉型別。
所謂列舉是指將變數的值一一列舉出來,變數只限於列舉出來的值的範圍內取值。 列舉的定義列舉型別定義的一般形式為: enum 列舉名  { 列舉值表 };
eg:enum weekday{sun,mon,tue,wed,thu,fri,sat};
注意
1.enum 變數型別還可以給其中的常量符號賦值,如果不賦值則會從被賦初值的那個常量開始依次加 1,如果都沒有賦值,它們的值從 0 開始依次遞增 1。 eg: 
enum Color
{
    GREEN = 1,
    RED,
    BLUE,
    GREEN_RED = 10,
    GREEN_BLUE<span style="white-space:pre">		</span>
}ColorVal;

其中各常量名代表的數值分別為:
GREEN = 1
RED = 2
BLUE = 3
GREEN_RED = 10
GREEN_BLUE = 11













   

   2.列舉元素不是變數,而是常數,因此列舉元素又稱為列舉常量。因為是常量,所以不能對列舉元素進行賦值。 

3.列舉值可以用來作判斷。例如: 
if (day==mon) {…} 
if (day>mon) {…} 
列舉值的比較規則是:按其在說明時的順序號比較,如果說明時沒有人為指定,則第一個列舉元素的值認作 0。例如,mon>sun,sat>fri。 
C 語言教程 ?216? 

4.一個整數不能直接賦給一個列舉變數,必須強制進行型別轉換才能賦值

。例如: 
day=(enum weekday)2; 
這個賦值的意思是,將順序號為 2 的列舉元素賦給 day,相當於workday=tue;

二、列舉與#define 巨集的區別
下面再看看列舉與#define 巨集的區別:
1), #define 巨集常量是在預編譯階段進行簡單替換。列舉常量則是在編譯的時候確定其值。
2),一般在編譯器裡,可以除錯列舉常量,但是不能除錯巨集常量。
3),列舉可以一次定義大量相關的常量,而#define 巨集一次只能定義一個。

下面再看看列舉與#define 巨集的區別:
1), #define 巨集常量是在預編譯階段進行簡單替換。列舉常量則是在編譯的時候確定其值。
2),一般在編譯器裡,可以除錯列舉常量,但是不能除錯巨集常量。
3),列舉可以一次定義大量相關的常量,而#define 巨集一次只能定義一個。

三、union共用體

1.    union 關鍵字的用法與 struct 的用法非常類似。
   union 維護足夠的空間來置放多個數據成員中的“一種”,而不是為每一個數據成員配置空間,在 union 中所有的資料成員共用一個空間,同一時間只能儲存其中一個數據成員,所有的資料成員具有相同的起始地址。例子如下:
union StateMachine
{
char character;
int number;
char *str;
double exp;
};
一個 union 只配置一個足夠大的空間以來容納最大長度的資料成員,以上例而言,最大長度是 double 型態,所以 StateMachine 的空間大小就是 double 資料型別的大小。

2.和struct的同與不同

union,中文名“聯合體、共用體”,在某種程度上類似結構體struct的一種資料結構,共用體(union)和結構體(struct)同樣可以包含很多種資料型別和變數。不過區別也挺明顯:

結構體(struct)中所有變數是“共存”的——優點是“有容乃大”,全面;缺點是struct記憶體空間的分配是粗放的,不管用不用,全分配。

而聯合體(union)中是各變數是“互斥”的——缺點就是不夠“包容”;但優點是記憶體使用更為精細靈活,也節省了記憶體空間。

   3.一個栗子
#include<stdio.h>  
union var{  
        long int l;  
        int i;  
};  
main(){  
        union var v;  
        v.l = 5;  
        printf("v.l is %d\n",v.i);  
        v.i = 6;  
        printf("now v.l is %ld! the address is %p\n",v.l,&v.l);  
        printf("now v.i is %d! the address is %p\n",v.i,&v.i);  
}  
結果:  
v.l is 5  
now v.l is 6! the address is 0xbfad1e2c  
now v.i is 6! the address is 0xbfad1e2c  
<span style="font-family: Arial; line-height: 26px;"><span style="color:#ff0000;">聯合體union所佔記憶體空間大小就是<span style="font-family: SimSun; line-height: 26px;">最大長度的資料成員</span></span></span>
4.大小端模式對 union 型別資料的影響
下面再看一個例子:
union
{
int i;
char a[2];
}*p, u;
p = &u;
p->a[0] = 0x39;
p->a[1] = 0x38;
p.i 的值應該為多少呢?
這裡需要考慮儲存模式:大端模式和小端模式。
大端模式( Big_endian):字資料的高位元組儲存在低地址中,而字資料的低位元組則存放
在高地址中。
小端模式( Little_endian):字資料的高位元組儲存在高地址中,而字資料的低位元組則存放
在低地址中。
union 型資料所佔的空間等於其最大的成員所佔的空間。對 union 型的成員的存取都是
相對於該聯合體基地址的偏移量為 0 處開始,也就是聯合體的訪問不論對哪個變數的存取都
是從 union 的首地址位置開始。
5.聯合體union適用場合:
union的使用場合,是各資料型別各變數佔用空間差不多並且對各變數同時使用要求不高的場合(單從記憶體使用上,我覺得沒錯)。

相關推薦

掃盲——C語言enum列舉型別union共用

一、列舉型別  enum: 在實際應用中,有的變數只有幾種可能取值。如人的性別只有兩種可能取值,星期只有七種可能取值。在 C 語言中對這樣取值比較特殊的變數可以定義為列舉型別。所謂列舉是指將變

C/C++開發C++之enum列舉量宣告定義使用與列舉類詳解與列舉類前置型別宣告

前面講到可以通過強制轉換將其他型別值賦給列舉變數:Weekday = enumType(2);這是合法的;但是Weekday = enumType(20);是非法的。這裡涉及列舉取值範圍的概念:列舉的上限是 大於最大列舉量的 最小的2的冪,減去1; 列舉的下限有兩種情況:一、列舉量的最小值不小於0,則列

資料結構C語言最基礎練習:棧的初始化,壓棧,出棧,遍歷,清空

隨手練習一下,詳細程式碼解釋都在程式碼片裡請仔細看看 如果有什麼不對的地方,請在下方留言 先建立標頭檔案: #define _CRT_SECURE_NO_WARNINGS 1 #ifndef _TEST_H #define _TEST_H //棧的鏈式儲存結構;

學習總結C語言的const到底修飾誰

不足之處還請指正。 const修飾的誰? 要在程式設計中多正確的使用const來使程式變得更加健壯。 《高質量C++/C程式設計指南》 const是修飾誰? #include <stdio.h

入門指導C語言難嗎?最難啃的三塊硬骨頭

先來看一個網友的對話: C語言說難也不難,開始接觸就是學習基礎,資料型別,函式格式,指標等等。越學越深入,越學視野越寬闊,只要認真看書,聽講,下來多練習,不難。 記憶體佈局 指標公認最難理解的概念,也是讓很多初學者選擇放棄的直接原因 指標之所以難理解,因為指標本身就是一個變數

易錯C語言結構記憶體對齊問題

對於一個結構體的位元組數大家有沒有遇到什麼疑問呢? 先看一個結構體: typedef struct Test { char a1; int a2; char a3; short a4; }Test_T; 在32位編譯系統下這一個結構體的位元組數是多少呢?是1+4

C 語言列舉型別Enum

列舉型別的定義形式為: enum typeName{ valueName1, valueName2, valueName3, ...... }; enum是一個新的關鍵字,專門用來定義列舉型別,這也是它在C語言中的唯一用途;typeName是列舉型別的名字;value

C語言enum列舉的用法

1.列舉體變數只能有固定的幾個值 如:先構建一個列舉體。 enum week{MON,TUE,WED,THU,FRI,SAT,SUN};再建立一個列舉體變數day enum week day;/

作業系統01C語言利用CerateProcess建立程序

一個環境塊存在於一個由以NULL結尾的字串組成的塊中,這個塊也是以NULL結尾的。每個字串都是name=value的形式。因為相等標誌被當做分隔符,所以它不能被環境變數當做變數名。與其使用應用程式提供的環境塊,不如直接把這個引數設為空,系統驅動器上的當前目錄資訊不會被自動傳遞給新建立的程序。對於這個情況的探

工作筆記C語言的字串真麻煩,好好梳理下

C的字串 C的字串很麻煩,不能像C++那樣對字串+ ,長度又不能隨便變。真TMD煩,有一句粗話真不知道當講不當講。時間全都浪費在處理字串上了。這個筆記中我要好好總結下,避免浪費時間。

學習拓展C語言 隨機數應用:偽隨機機制

一、總論 1.偽隨機機制的意義 1.1 什麼是偽隨機機制 日常生活中大家都喜歡玩單機或者網路遊戲,而在這些遊戲中常常會存在隨機,比如暴擊率20%或者被動擊暈15%等等,而在這些隨機事件中,我們往往被告知這些隨機事件也能分成兩類:一類是固定的概率,常被稱

C語言列舉型別

在C語言中,列舉型別(enumerated type)宣告符號名稱來表示整形常量。使用enum關鍵字,可以建立一個新“型別”並指定它可具有的值,如: //建立spectrum作標記名,那enum spectrum作為一個型別名使用 enum spectrum { red, orange,

有關C語言列舉型別和gotobreak和continue語句

有關C語言的列舉型別和goto、break和continue語句 今天我們首先來看一下列舉型別,因為這個真的很容易讓人忘記,感覺平常都用不上的角色,所以今天特意將它拿出來講解一下 首先我們看一下列舉的一般用法 typedef enum { sun = 1, mon=2,

C#中Enum列舉型別的簡單使用

列舉型別的介紹:  列舉型別是由一組特定常量構成的一組資料結構,是值型別的一種特殊形式,當需要一個由指定常量集合組成的資料型別時,使用列舉型別。列舉宣告可以顯式地宣告 byte、sbyte、short

C語言列舉型別

在列舉型別的定義中列出所有可能的取值,被說明為該列舉型別的變數取值不能超過定義的範圍。應該說明的是,列舉型別是一種基本資料型別,而不是一種構造型別,因為他不可能再分解為任何基本型別。 列舉型別的定義如下: enum 列舉名 {列舉值表}; 例: enum weekday { sun,mou, tue,

編程基礎C語言常見宏定義

ifd 轉換成 erro get 程序 運算 efi 宏定義 當前 我們在使用C語言編寫程序的時候,常常會使用到宏定義以及宏編譯指令,有的可能比較常用,有的可能並不是很常用,是不是所有的C語言宏定義以及宏指令你都清楚呢? 指令 用途詳細介紹 # 空指令,無任何效果 #i

C語言之變量存儲類型

art 技術分享 .net ont alt enter fill img 分享 【精】C語言之變量存儲類型

C語言文件操作詳解

pri void rfi 識別 archive format 隨機 stat 文本文 轉自:http://www.cnblogs.com/likebeta/archive/2012/06/16/2551780.html C語言中沒有輸入輸出語句,所有的輸入輸出功能都用

C語言 printf格式控制符 完全解析

china int 數字 大於 轉換 OS 組成 字符數 無符號 printf的格式控制的完整格式:% - 0 m.n l或h 格式字符下面對組成格式說明的各項加以說明:①%:表示格式說明的起始符號,不可缺少。②-:

STLHDU2024C語言合法標識符水題

AI info targe == () 簡潔 技術分享 type #define 鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2024 既然要求了全體同學都要刷完杭電100題,那我還是以身作則,也都給刷完吧~~~ 這些水題真的是