enum in c language

今天說說C語言中的枚舉。

參考:Enumeration (or enum) in C

1 定義

定義一個枚舉類型很容易:

enum aa { a1, a2, a3 };

這里

  • enum是關鍵字
  • aa是枚舉變量,也就是我們自定義類型
  • a1,a2,a3是枚舉成員

然后怎么使用呢?

首先,它就像結構體struct和聯合體union那樣,是一個自定義的數據類型,用它定義變量,也是一樣的:

enum aa abc; 	// 定義變量
enum aa *en_p; 	// 定義指針

是的,它跟基本數據類型以及結構體等特殊數據類型一樣,都可以定義變量和定義指針

所以,和int一樣,如果僅僅定義,而沒有賦值和使用,編譯后它就沒了,變量定義本身不占地方,賦值了才占地方。

另外,和struct一樣,它只是一個結構,這個結構是C語言層級的聲明,編譯后不存在這個結構的,匯編層級沒有的。

所以,下面我們先說說,變量的賦值

2 變量的賦值

枚舉類型的賦值其實是比較復雜的,先說最常用的。

2.1 默認值

enum aa { a1, a2, a3 };

對于上述枚舉類型,它的a1 a2 a3, 在默認情況下,會被賦值為

a1 = 0;
a2 = 1;
a3 = 2;

2.2 賦初值

enum aa { a1 = 1, a2 = 3, a3 = 5 };

可以對其任意賦初值,這樣,三個枚舉成員的值就對應了你指定的值了。

我們看看多種情況:

情況1:全都賦初值

enum aa { a1 = 1, a2 = 3, a3 = 5 };

情況2:有重復的初值

這種情況的完全可以的。

enum aa { a1 = 1, a2 = 1, a3 = 5 };

情況3:部分賦初值,部分不賦值

enum aa { a1 = 1, a2, a3 };

對于此時,a2 = 2 a3 = 3,也就是說,后面沒有賦值的,是默認根據前面賦值的累加的

enum aa { a1 = 1, a2, a3, a4 = 10, a5, a6 };

那這種情況呢?

  • 根據a1累加:a2 = 2 a3 = 3 a4 = 4
  • 根據a4累加:a5 = 11 a6 = 12

賦值范圍

與int類型賦值范圍一樣!賦值-1什么的也可以,與int類型的范圍一樣的。

2.3 變量賦值

其實就是定義一個變量,然后給它賦值,這里不一樣的是,枚舉成員本身,就代表值

enum aa { a1 = 1, a2, a3, a4 = 10, a5, a6 };
enum aa abc = a2;

這個時候,abc = 2a2就代表數值2.

從其他角度理解,enum aa abc = a2;的含義就是

int a2 = 2;
int abc = a2;

就是這么個意思。

2.4 指針賦值

enum aa abc = a2;  
enum aa *enu_p = &abc;
printf("%d\n", *enu_p);		

沒啥好說的,跟基本數據類型指針待遇一樣的。

3 談談枚舉成員

3.1 作用范圍

首先,結構體本身

enum aa { a1 = 1, a2, a3, a4 = 10, a5, a6 };

它的作用范圍,跟struct一樣,跟int也一樣,{ } 里面就是局部變量,在最外面就是全局變量,對于aa這個自定義類型標識符,也是一樣的,不多說了。

比較需要注意的是,枚舉成員也是標識符

3.2 枚舉成員也是標識符

我們上面的例子,a1,a2,a6這些,在其作用域內,也是標識符,也就是相當于你定義了一個int a1;一樣,在作用域內不能重復定義了!并且,這個標識符本身代表了一個int值。

int main(){enum aa { a1 = 1, a2, a3, a4 = 10, a5, a6 };int a1; // error!重定義了!上面定義過a1了!enum bb {a2,a4}; // error!
}

4 enum與int

enum中的枚舉成員,都是int類型的變量,也代表int類型的值,值的范圍也是int的范圍。

5 enum與#define

5.1 共同點

下面兩段代碼基本來說是等價的:

#define Working 0
#define Failed 1
#define Freezed 2
enum state  {Working, Failed, Freezed};

5.2 enum的優勢

#define是全局的,而enum則是與基本數據類型一樣,范圍非常靈活。

5.3 #define的優勢

enum只能定義int類型值,define什么都可以等價,任何值,以及函數,都可以。

6 enum的大小(size)

6.1 變量的大小

注意:討論enum結構本身大小沒必要,因為其變量,就是這個結構的實例化,這一點和struct一樣的!

enum aa { a1 = 10, a2, a3 };
enum aa abc = a2;
printf("size = %d\n", sizeof(enum aa)); // 4 
printf("size = %d\n", sizeof(abc));		// 4

試一下就知到了,都是4字節。這倆肯定相等,一個是模板,一個是實例

為什么是4呢?

因為enum這里面的值,其實就是int類型的,那不就是4嗎!然后這個枚舉變量,值只能有一個吧,那就占一個4字節空間足夠了。

像struct那是可以有多個值,所以每個變量都占空間,這個就沒必要,一堆里面選一個就可以了。

另外就是,不要試圖獲取枚舉成員的地址,因為它有沒有用上場都不一定呢,它只是C語言層級的一個值而已,不一定被分配

在這里插入圖片描述

好吧,沒人這么閑的沒事干。

7 奇奇怪怪

enum aa abc = 100;
printf("***%d\n", abc); // 100

這種情況下,就真的當int用了,其實也沒啥,反正編譯器允許,不過一般沒人這么干。

8 最后,說說真正常用的地方

說實話,說了這么多,基本都很少用得到!常用的地方也就固定套路,內些野路子你看看就好。

就比如你定義個月份什么,星期什么的。

#include<stdio.h>enum year{Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};int main()
{int i;for (i=Jan; i<=Dec; i++)      printf("%d ", i);return 0;
}

另外還有就是,編譯原理中的,詞法分析器的單詞表,需要把編號和名稱對應起來,enum是天然適合的結構,使用struct嵌套enum和其他,就很完美很方便。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384607.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384607.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384607.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

信號量SIGCHLD的使用,如何讓父進程得知子進程執行結束,如何讓父進程區分多個子進程的結束

本教程基于 Ubuntu 20.10 gcc 10.2.0. 示例程序如果不能正常編譯和執行&#xff0c;說明您系統和工具版本與我的不匹配&#xff0c;請自行查閱資料。 0 概述 先給出該信號的描述&#xff1a; SignalValueDescriptionSIGCHLD17Child status has changed (POSIX). Signal sent …

使用gdb調試多進程程序、同時調試父進程和子進程

參考: [1] GDB debugging multi-process programs [2] Debugging programs with multiple processes 根據這兩篇參考鏈接&#xff0c;完全可以實現使用gdb同時調試父進程和子進程。 接下來說明一下可能遇到的坑 gdb8.1版本有bug&#xff0c;設置完set detach-fork-on off&…

Linux安裝Ncurses庫

參考&#xff1a;How To Install Ncurses Library In Linux 針對Ubuntu說明一下&#xff1a; wget https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.2.tar.gz&#xff0c;至于最新版本&#xff0c;自己看官網&#xff0c;修改一下版本號即可。tar xzf ncurses-6.2.tar.gzcd nc…

gdb 10.2的安裝

參考 [1] GDB-10.2 [2] README for GDB release 個人系統 Ubuntu20.10。 注意gdb10.2需要c11語法&#xff0c;需要安裝g 下載安裝包wget https://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.xz解壓縮tar -xvzf gdb-10.2.tar.xz進入解壓之后的目錄mkdir buildcd build配置&#xff0c;…

gdb tui的使用

[1] GDB Text User Interface [2] GDB Text User Interface 簡單來說&#xff0c;進入gdb之后&#xff0c;使用ctrl x 2就足夠了。其他細節請參考上述鏈接&#xff0c;選一個就可以。

C語言中信號函數(signal)的使用

先來簡單談談C語言中的信號&#xff08;signal&#xff09; 首先&#xff0c;signal是C語言庫中的函數&#xff0c;它實際上是軟中斷&#xff0c;也就是軟件發出的終端&#xff0c;本質來說&#xff0c;類似于int n。 對于接收到該軟中斷信號的進程&#xff0c;就會停下手頭的…

UNIX哲學

參考&#xff1a; 對比Linux與Windows 使用Linux想要做某些事情的時候&#xff0c;就拆開想&#xff0c;想想我需要哪些功能&#xff0c;需要哪些工具&#xff0c;依次怎么執行&#xff0c;然后用管道建立連接&#xff0c;讓數據依次流過不同的工具&#xff0c;從而得到最終結果…

fork創建多個子進程

references: [1] how to create two processes from a single Parent [2] fork() in C [3] linux中fork同時創建多個子進程的方法 fork的本質&#xff0c;就是復制&#xff0c;把當前進程復制一份&#xff0c;然后兩個進程并發地執行fork后面的語句&#xff0c;區別就是&#x…

wait系統調用

reference:Wait System Call in C 只強調幾點&#xff0c;剩下的直接看參考鏈接內容就好了&#xff0c;不是偷懶&#xff0c;而是里面內容寫的很好了&#xff0c;沒必要再寫一遍了&#xff0c;這種東西就是單純的系統調用而已&#xff0c;理解了功能&#xff0c;就完事了&#…

Linux進程間通信:共享內存與管道

references: [1] IPC through shared memory [2] Inter Process Communication (IPC) [3] https://www.geeksforgeeks.org/pipe-system-call/ [4] watch command in Linux with Examples 參考鏈接1和2是介紹了共享內存IPC的簡單原理和相關系統調用的使用參考鏈接3是介紹了管道通…

find command基本使用

find命令通常用于根據文件名查找文件&#xff0c;這是最基本用法。 find [path] -name/-iname [filename] path寫要查找的路徑&#xff0c;自動遞歸查找filename寫文件名&#xff0c;可以使用通配符*還有其他什么的表達式 具體細節請man find查閱文檔。

正則表達式特別需要注意的點:“空“字符的匹配

在正則表達式中&#xff0c;[...]代表1個字符&#xff0c;不管里面有多少字符&#xff0c;最終這個東西的結果都是1個字符。 對于表達式[^a]表達的匹配除了a之外的字符&#xff0c;并且是1個字符。 需要注意的是&#xff0c;有些特殊字符是不會被匹配的。 我們看一個示例&am…

vim多列操作--插入/刪除

插入 How to insert text at beginning of a multi-line selection in vi/VimVim Commands 刪除 ctrl v使用上下左右鍵選中一片區域按d刪除

vim進行行內某部分的復制剪切粘貼

ctrl v使用方向鍵選中你要復制的部分 按d&#xff08;剪切&#xff09;或者按y&#xff08;復制&#xff09;再移動到你的目標位置&#xff0c;按p粘貼&#xff08;在正常模式下才行&#xff0c;如果不是&#xff0c;先按esc&#xff09; 這個過程與你操作word文檔的復制粘貼…

函數調用堆棧

基于孟寧老師的Linux內核分析 1 int g(int x){ 2 int y x 3;3 return y;4 }5 6 int f(int x){7 int z x 10;8 return g(z);9 }10 11 int main(){12 int a f(8) 1;13 return 0;14…

gdb調試的幾點提示(1)

GDB debugger Examining Memory Continuing and Stepping How to translate a virtual memory address to a physical address? s和n是C語言的下一步 si和ni是匯編語言下一步 gdb能夠查看的都是虛擬地址&#xff0c;不能查看物理地址&#xff0c;應用程序都不能查看物理地址…

C語言讀取文件

C語言一次性讀取文件 C - File I/O C library function - fread() 需要注意的點 fgets函數&#xff0c;一次只能讀取一行&#xff0c;并且在結尾自動添加\0fread函數&#xff0c;可以讀取很多內容&#xff0c;但是不會添加\0需要手動完成&#xff0c;具體看[參考1]

Vivado提高綜合和實現的速度

讓計算機的資源盡可能給vivado&#xff0c;綜合、實現的時候修改一個參數 jobs改為你的計算機的最大值&#xff0c;我的計算機是12核的。 速度會快很多&#xff01;

安裝Ubuntu RISC V toolchain失敗(網速、git配置原因)

git獲取大容量工程出錯&#xff1a;RPC failed&#xff1b; curl GnuTLS recv error : Decryption has failed. error: RPC failed; curl 56 GnuTLS recv error (-54): Error in the pull function.fatal: The remote end 官方GitHub倉庫 gitee鏡像倉庫 如果網速不夠&#xff0…

Linux環境變量 set env export區別

參考鏈接 How to Set Environment Variables in Linux set 他能夠顯示當前shell的環境變量 它針對的對象是當前shell&#xff0c;如果關閉了就沒了&#xff01; 直接使用set --help查看就可以。 env 顯示當前用戶的環境變量&#xff0c;針對的當前登錄的用戶 export 它能…