網站首頁 編程語言 正文
前言
在C語言中,有三個自定義類型——結構體,枚舉,聯合,自定義類型出現是為了解決內置類型無法解決的問題。例如人這個對象,如果要描述人這樣一個復雜對象,就不只是一個簡簡單單的int、char、double類型的數據能描述的,這時候就需要我們使用自定義類型來描述。
(PS:內置類型是指任何語言在設計初期定義的類型,如c語言中的int, double, char… 它也是在一種語言中最基本的類型,與編譯器編譯出的代碼具有重大關系,值得一提的是,不同語言也擁有不同的內置類型,但是所有內置類型的定義都與計算機的運算方式相關。)
對于結構體來說,我們應該都不陌生,結構體很重要,內容也很多,我之前寫過一篇關于結構體的文章,不過那篇文章寫的都是結構體的一些基礎內容,過兩天會寫一篇進階的,所以現在在就先不講結構體了,我們先認識一下另外兩個自定義類型。
枚舉
枚舉的定義
枚舉類型的定義要使用enum關鍵字,舉個例子,如果我要用枚舉常量才定義一下三原色,也就是紅藍綠(RGB)。請看下面這段代碼:
enum Color
{
//枚舉常量
RED,
GREEN,
BLUE
};
Color就被定義成了枚舉類型,{}中的內容是枚舉類型的可能取值,也就是枚舉常量。(補充:對于#define和嗎枚舉定義的常量 一般把變量名寫成大寫)。
枚舉的使用
如果要用枚舉類型創建變量就要使用enum Color,enum Color就代表著枚舉類型,而創建好的變量的值就只能是{}中的內容。如下:
enum Color a = RED;
enum Color b = GREEN;
enum Color c = BLUE;
枚舉常量是不能改變的。但是這些枚舉常量都是有值的,默認從0開始,一次遞增1,當然在定義的時候也可以賦初值。給大家解釋一下,看下面這段代碼:
printf("%d\n", RED);
printf("%d\n", GREEN);
printf("%d\n", BLUE);
我想看到這大家應該明白這是什么意思了,枚舉常量是有值的,數值從0開始依次加1。如果要改變初始的值,只需要給第一個枚舉常量賦值就行。例如:
enum Color
{
//枚舉常量
RED = 2,
GREEN,
BLUE
};
像這樣,再去打印RED,GREEN和BLUE,值就是2,3,4。
枚舉的優點
對于枚舉,我們可以使用 #define 定義常量,為什么非要使用枚舉?
枚舉的優點:
- 增加代碼的可讀性和可維護性
- 和#define定義的標識符比較枚舉有類型檢查,更加嚴謹。
- 防止了命名污染(封裝)
- 便于調試
- 使用方便,一次可以定義多個常量
聯合(共用體)
在進行某些算法的C語言編程的時候,需要使幾種不同類型的變量存放到同一段內存單元中。也就是使用覆蓋技術,幾個變量互相覆蓋。這種幾個不同的變量共同占用一段內存的結構,在C語言中,被稱作“共用體”類型結構,簡稱共用體,也叫聯合體。
聯合體的定義
聯合體的定義與結構體比較相似,要先聲明聯合體,要使用union這個關鍵字,聲明方式如下:
union MyUnion
{
int a;
char b;
};
聯合體的定義如下:
//union 類型名 變量名
union MyUnion un;
這樣就創建好了un這個聯合體類型。
聯合體的特點
先看這段代碼以及運行結果:
union MyUnion
{
int a;//4
char b;//1
};
int main()
{
union MyUnion un;
printf("%d\n", sizeof(un));
printf("%u\n", &(un));
printf("%u\n", &(un.a));
printf("%u\n", &(un.b));
return 0;
}
我們可以看到un的大小是4不是5,而且un,un.a和un.b的地址是一樣的。為什么?
下面我給大家一一解釋:
我們在創建變量時,編譯器就會給我們開辟一些空間,因此我創建un變量時,編譯器就已經給我開辟空間了,那么我在打印un地址時,打印的就是un的首地址。在64位環境下,int是4個字節,char是一個字節,它們的地址和un是一樣的,說明int是從un的首地址開始向后占用4個字節的空間,char也是從un的首地址開始的。因此打印出來的un.a和un.b的地址是相同的。它們公用同一部分的內存空間,這就是聯合體。
聯合體大小的計算
1.聯合的大小至少是最大成員的大小。
2.當最大成員大小不是最大對齊數的整數倍的時候,就要對齊到最大對齊數的整數倍。
對于第一條,上面的例子證明過了,接下來重點來看第二條。看一下下面這段代碼:
union un
{
char c[5];
int i;
};
int main()
{
printf("%d\n", sizeof(union un));
return 0;
}
對于這段代碼,最后輸出的結果是什么?5?
答案是8.
為什么?
對于un里面有一個長度為5的字符數組c和一個整型i。我們可以把它看成5個字符變量和一個整型變量。那么在計算聯合體大小的時候,對齊數就是int類型,也就是4個字節,而不是5個字節。
因此我們計算聯合體大小,考慮以多少字節為對齊數時,就只需要看數據類型就可以了,然后再看多少最大對齊數的整數倍能放下最大的變量就可以了。
總結
自定義類型中枚舉和聯合體的難度不是很大,也就聯合體大小的計算有點難度。大家只要記住計算聯合體大小的兩個特點就可以了。(感謝您的觀看,如有錯誤,歡迎指正!感謝!)
原文鏈接:https://blog.csdn.net/m0_63463510/article/details/126906176
相關推薦
- 2022-10-23 C#各種異常處理方式總結_C#教程
- 2022-09-26 網絡瀏覽器中運行Python腳本PyScript剖析_python
- 2022-05-13 windwos11 小愛音箱鏈接上但是沒有聲音
- 2022-12-21 OpenHarmony實現屏幕亮度動態調節方法詳解_Android
- 2023-02-15 C#?9使用foreach擴展的示例詳解_C#教程
- 2023-07-16 uni-app uni.switchTab和uni.reLaunch跳轉tabbar頁面
- 2022-04-16 pycharm如何為函數插入文檔注釋_python
- 2022-12-01 Flutter路由框架Fluro使用教程詳細講解_Android
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支