自定義類型:結構體、聯合與枚舉(2)

目錄

前言

一、?聯合體類型的聲明

介紹:

注意:

二、?聯合體的特點

介紹:

代碼舉例:

三、聯合體??的計算

介紹:

聯合體大小的計算規則

1. 基礎規則

1. 確定最大成員大小

2. 計算對齊模數的最小公倍數

3. 最終大小

結論

關鍵總結

結論

四、枚舉類型的聲明

介紹:

五、枚舉類型的優點

介紹:

總結


前言

上一篇文章講解結構體類型的聲明、結構體變量的創建和初始化、結構成員訪問操作符、結構體內存對?知識的相關內容,本篇文章將講解聯合體類型的聲明、聯合體的特點、聯合體??的計算、枚舉類型的聲明、枚舉類型的優點、枚舉類型的使?知識的相關內容。

一、?聯合體類型的聲明

介紹:

在C語言中,聯合體(Union)?是一種特殊的數據類型,它允許在同一段內存空間中存儲不同類型的數據,但同一時刻只能保存其中一種類型的值。以下是聯合體類型的常見聲明方式:

union 聯合體標簽名 {成員類型1 成員名1;成員類型2 成員名2;// ... 其他成員
};
  • 使用場景:聲明后可通過?union 聯合體標簽名?定義變量。

代碼例:

union Data {int num;float f;char str[20];
};
union Data data; // 定義聯合體變量

注意:

1.像結構體?樣,聯合體也是由?個或者多個成員構成,這些成員可以是不同的類型。

2.聯合體的關鍵字是union. 但是編譯器只為最?的成員分配?夠的內存空間。

3.聯合體的特點是所有成員共?同?塊內存空間。所 以聯合體也叫:共?體。 給聯合體其中?個成員賦值,其他成員的值也跟著變化。

二、?聯合體的特點

介紹:

聯合的成員是共?同?塊內存空間的,這樣?個聯合變量的??,?少是最?成員的??(因為聯合 ?少得有能?保存最?的那個成員)。

代碼舉例:

#include <stdio.h>
//聯合類型的聲明
union Un
{char c;int i;
};
int main()
{
//聯合變量的定義union Un un = {0};
//輸出的結果是?樣的嗎?printf("%p\n", &(un.i));printf("%p\n", &(un.c));printf("%p\n", &un);return 0;
}

由此我們可以得出聯合的成員是共?同?塊內存空間的,那么,改其中一個成員的地址,其他成員的地址受到影響嗎?

例:


#include <stdio.h>
//聯合類型的聲明
union Un
{char c;int i;
};
int main()
{
//聯合變量的定義union Un un = {0};un.i = 0x11223344;un.c = 0x55;printf("%x\n", un.i);return 0;
}

由代碼以及結果,我們可知:我們改其中一個成員的地址,其他成員的地址受到影響,通過改c,將i的第4個字節的內容修改為55了。

這處我們通過圖來講解:

詳細講解:

    • union Un?包含?char c(1字節)和?int i(4字節),因此聯合體大小為?4字節(取最大成員?int?的大小)。
    • 所有成員共用這4字節內存,c?存儲在內存的最低地址字節(取決于系統字節序,默認這是小端字節序,即低字節存低位數據)。
  1. 初始賦值與修改過程

    • 步驟1un.i = 0x11223344
      在小端字節序下,4字節內存的存儲形式為(從低地址到高地址):
      44(0x44)、33(0x33)、22(0x22)、11(0x11)。

    • 步驟2un.c = 0x55
      char c?會覆蓋內存中最低地址的1字節,將原?44?替換為?55。此時內存變為:
      55(0x55)、33(0x33)、22(0x22)、11(0x11)。

  2. 最終讀取?un.i?的值
    內存中的4字節數據組合為?0x11223355(高地址字節?11?為最高位,低地址字節?55?為最低位),因此?printf("%x\n", un.i)?輸出?11223355

既然聯合體是公用內存,那我們來對??下相同成員的結構體和聯合體的內存布局情況。

先列出聯合體:

#include <stdio.h>
union Un
{char c;int i;
};
int main()
{   union Un un = {0};printf("%p\n", &(un.i));printf("%p\n", &(un.c));printf("%p\n", &un);return 0;
}

結構體:

#include <stdio.h>
struct s
{char c;int i;
};
int main()
{   struct s un = {0};printf("%p\n", &(un.i));printf("%p\n", &(un.c));printf("%p\n", &un);return 0;
}

結合圖:

三、聯合體??的計算

介紹:

聯合體計算大小和結構體相同,有內存對齊規則:

下面解釋一下:

聯合體大小的計算規則

聯合體(Union)的大小由最大成員的大小內存對齊規則共同決定,核心原則是:聯合體的總大小必須能容納最大的成員,且滿足所有成員的對齊要求

1. 基礎規則
  • 取最大成員大小:聯合體的大小首先至少是所有成員中占用內存最大的那個成員的大小。
  • 滿足內存對齊:最終大小需向上調整為所有成員對齊模數的最小公倍數的倍數(對齊模數通常為成員類型的大小,如int為4字節,double為8字節等)。

列舉下例子:

union Test1 {char a;    // 1字節int b;     // 4字節double c;  // 8字節
};

1. 確定最大成員大小
  • 成員?achar):1字節
  • 成員?bint):4字節
  • 成員?cdouble):8字節
  • 最大成員大小 = 8字節double c)。
2. 計算對齊模數的最小公倍數

各成員的對齊數(通常為類型大小):

  • char:1字節
  • int:4字節
  • double:8字節 (最?對?數)
  • 最小公倍數 = 8(1、4、8的最小公倍數為8)。
3. 最終大小

聯合體大小需滿足:

  • 容納最大成員(8字節);
  • 是對齊模數最小公倍數(8)的倍數。

因此,union Test1?的大小為 8字節??。

結論

union Test1?在內存中占用?8字節,由最大成員?double c?的大小和對齊要求共同決定。

例:

#include <stdio.h>
union Un1
{char c[5];int i;
};
union Un2
{short c[7];int i;
};
int main()
{printf("%d\n", sizeof(union Un1));printf("%d\n", sizeof(union Un2));return 0;
}

接下來,將對其詳解:

union Un1?的大小計算

  • 最大成員大小char c[5]?占5字節(大于?int i?的4字節)。
  • 對齊模數
    • char?數組的對齊數 = 1字節(基礎類型?char?的大小);
    • int?的對齊數 = 4字節。
    • 最小公倍數 =?4(1和4的最小公倍數)。
  • 調整對齊:5字節需向上調整為4的倍數(5 → 8,因為 4×2=8)。
  • 結果sizeof(union Un1) = 8

2.?union Un2?的大小計算

  • 最大成員大小short c[7]?占14字節(大于?int i?的4字節)。
  • 對齊模數
    • short?數組的對齊數 = 2字節(基礎類型?short?的大小);
    • int?的對齊數 = 4字節。
    • 最小公倍數 =?4(2和4的最小公倍數)。
  • 調整對齊:14字節需向上調整為4的倍數(14 → 16,因為 4×4=16)。
  • 結果sizeof(union Un2) = 16

關鍵總結

聯合體大小需同時滿足?“容納最大成員”?和?“對齊模數最小公倍數的倍數”?兩個條件,當最大成員大小不滿足對齊要求時,需向上補齊 💡。

注意:基礎類型?short?的大小為2個字節。

當然,聯合體可以幫助我們解決很多問題,例如:求系統的大小端字節序:

如果不了解的可一看一下數據在內存中的存儲該章節內容。

#include <stdio.h>
union Un1
{int i;char c;};
int main()
{union Un1 a;a.i=1;a.c=*((char*)&a.i);if(a.c==1){printf("小端字節序\n");}else{printf("大端字節序\n");}return 0;
}

解釋:

  • 聯合體成員共享同一塊內存空間,i?和?c?的起始地址相同。
  • char c?僅訪問內存中?第一個字節?的數據。

字節序判斷原理

  • a.i = 1:將整數?1?存入?int i,其二進制表示為(假設32位系統):
    00000000 00000000 00000000 00000001(高位字節在前,低位字節在后)。

  • 字節序影響內存存儲

    • 小端字節序:低位字節存低地址 → 第一個字節為?00000001(值為1)。
    • 大端字節序:高位字節存低地址 → 第一個字節為?00000000(值為0)。
  • a.c = *((char*)&a.i):直接讀取?i?的第一個字節數據到?c

條件判斷結果

  • 若?a.c == 1?→ 第一個字節為?1?→?小端字節序。
  • 若?a.c == 0?→ 第一個字節為?0?→?大端字節序

結論

程序通過聯合體共享內存的特性,讀取整數?1?的第一個字節數據,最終判斷當前系統為?小端字節序?💡。

四、枚舉類型的聲明

介紹:

枚舉顧名思義就是??列舉,把可能的取值??列舉。

代碼示例:

enum Color{RED,GREEN,BLUE
};

詳解:

  1. 默認值規則

    • 首個常量默認值為?0,后續常量默認值為?前一個常量值 + 1
    • 可通過?=?顯式指定任意整數(支持負數),未指定的后續常量自動遞增。
enum Color{RED=2,GREEN,BLUE
};

這樣實現。

五、枚舉類型的優點

介紹:

1. 增加代碼的可讀性和可維護性。

2. 和#define定義的標識符?較枚舉有類型檢查,更加嚴謹。

3. 便于調試,預處理階段會刪除 #define 定義的符號。

4. 使??便,?次可以定義多個常量。

5. 枚舉常量是遵循作?域規則的,枚舉聲明在函數內,只能在函數內使?。

使用示例:

#include <stdio.h>// 聲明并定義枚舉
typedef enum {SPRING = 1,  // 顯式從1開始SUMMER,      // 2AUTUMN,      // 3WINTER       // 4
} Season;int main() {Season s = SUMMER;printf("當前季節編號:%d\n", s);  // 輸出:2return 0;
}

總結

?以上就是今天要講的內容,本文介紹了聯合體類型的聲明、聯合體的特點、聯合體??的計算、枚舉類型的聲明、枚舉類型的優點、枚舉類型的使?知識的相關內容,為本章節知識的內容,希望大家能喜歡我的文章,謝謝各位,同時自定義類型:結構體、聯合與枚舉部分也結束了,下篇文將為大家帶來新的知識。

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

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

相關文章

Oceanbase下使用TPC-H模式生成數據

1.下載tpc-h http://www.tpc.org/ 點擊下載始終彈出這個畫面&#xff0c;嘗試了多種方法無效&#xff0c;最后選擇科學上網工具&#xff0c;才正常下載。 通過網盤分享的文件&#xff1a;TPC-H-Toolv3.zip 鏈接: https://pan.baidu.com/s/14CXrp7v_7XkPtXfFLkziBQ?pwdqf5t 提…

LeetCode 面試經典 150_哈希表_單詞規律(41_290_C++_簡單)

LeetCode 面試經典 150_哈希表_單詞規律&#xff08;41_290_C_簡單&#xff09;題目描述&#xff1a;輸入輸出樣例&#xff1a;題解&#xff1a;解題思路&#xff1a;思路一&#xff08;哈希表&#xff09;&#xff1a;代碼實現代碼實現&#xff08;思路一&#xff08;哈希表&a…

librespeed c++ 上傳下載帶寬測試 排坑全流程

在搭建 LibreSpeed 測速服務并實現基于 curl/API 的上傳下載測試時&#xff0c;遇到 Nginx 配置沖突、PHP 權限異常等問題。本文將梳理從環境搭建到功能驗證的全流程&#xff0c;針對 “curl 上傳報 404/405”“PHP-FPM 權限拒絕”等典型問題&#xff0c;提供可復現的解決方案。…

重讀生成概率模型1----基礎概念

1 KL 散度 KL 散度的作為是描述兩個分布的差異的&#xff0c;首先是度量一個分布&#xff0c;用熵來度量。 1.1 熵 在介紹熵之間&#xff0c;首先要度量單個事件的信息量 I(x)?logP(x)I(x)-logP(x)I(x)?logP(x) 整體的信息量 H(P)Ex P[?logP(x)]?∑P(x)logP(x) \begin{alig…

排查解決磁盤占用高問題(容器掛載的磁盤)

最近遇到磁盤占用高的告警&#xff0c;記錄一下解決的思路。 首先是系統觸發告警&#xff0c;通知我們某臺機器磁盤占用高。&#xff08;或其他途徑得知&#xff09; 通過XShell登錄該機器。 執行df-h命令查看掛載占用情況找到真正占用高的掛載點掛載點/home目錄占用高&#xf…

流體(1)

流體 Minecraft 中的流體(Fluid),也常被稱為液體(Liquid),是一類能夠自由流動、形成河流、瀑布或湖泊的特殊方塊。它們的行為基于簡化的流體力學,是游戲世界中動態環境的重要組成部分。 ?? 流體是什么? 在 Minecraft 中,流體核心特點包括: 源方塊與流動:每個流…

機器學習-卷積神經網絡(CNN)

全連接層->卷積層 用有一個隱藏層的MLP訓練ImageNet數據集&#xff08;300*300的圖像&#xff0c;有1000個類別&#xff09;&#xff0c;要有10000個輸出 會有10億個可學習的參數&#xff0c;量太大 全連接&#xff1a;一個輸出是根據所有輸入加權得到在圖片中識別物體&…

Ubuntu 磁盤擴容與擴容失敗問題解決( df -h 與 GParted 顯示空間不一致的問題 -LVM)

在管理 Linux 磁盤時&#xff0c;你是否遇到過這樣的困惑&#xff1a;正常擴容之后&#xff0c;發現GParted 顯示某個分區還有幾十 GiB 可用&#xff0c;但 df -h 卻提示該分區已接近滿額&#xff1f;這種 “空間幻覺” 背后是系統存儲管理的分層設計&#xff0c;本文將從原理到…

PyQt5中QLineEdit控件數值顯示與小數位數控制

在PyQt5應用程序開發中&#xff0c;QLineEdit控件常用于顯示和編輯文本內容。當需要用它來顯示數值并控制小數位數時&#xff0c;開發者需要掌握一些特定的技巧。本文將深入探討幾種實現方法&#xff0c;每種方法都附帶完整獨立的代碼示例。 數值格式化基礎 在Python中&#xf…

LangChain使用方法以OpenAI 的聊天模型GPT-4o為例

以使用 OpenAI 的聊天模型&#xff08;如 GPT-4&#xff09;為例&#xff0c;從設置環境、初始化模型、調用模型到處理響應的各個方面進行介紹&#xff1a; 1. 環境設置 安裝 langchain-openai 包。設置環境變量 OPENAI_API_KEY&#xff0c;用于認證&#xff08;以linux為例&am…

Oracle為數據大表創建索引方案

在日常業務中&#xff0c;避免不了為數據量大表補充創建索引的情況&#xff0c;如果快速、有效地創建索引成了一個至關重要的問題&#xff08;注意&#xff1a;雖然提供有ONLINE在線執行的方式&#xff0c;理想狀態下不會阻塞DML操作&#xff0c;但ONLINE在開始、結束的兩個時刻…

網站服務相關問題

目錄 HTTP常見的狀態碼 http和https的區別以及使用的端口號 http處理請求的過程 https認證過程 正向代理和反向代理的區別 HTTP常見的狀態碼 HTTP&#xff08;超文本傳輸協議&#xff09;定義了一系列的狀態碼&#xff0c;用于表示客戶端請求的處理結果。以下是一些常見的…

Go并發編程實戰:深入理解Goroutine與Channel

Go并發編程實戰&#xff1a;深入理解Goroutine與ChannelGo并發編程實戰&#xff1a;深入理解Goroutine與Channel概述1. 為什么是Go的并發&#xff1f;從“線程”與“協程”說起2. Goroutine&#xff1a;如何使用&#xff1f;3. Channel&#xff1a;Goroutine間的安全通信創建與…

2025服貿會“海淀之夜”,點亮“科技”與“服務”底色

2025年9月12日傍晚&#xff0c;北京頤和園&#xff0c;十七孔橋旁&#xff0c;2025年中國國際服務貿易交易會“海淀之夜”如約而至。在“海淀之夜”&#xff0c;科技機構、金融機構、咨詢服務機構、出海服務企業以及跨國企業和國際友人等&#xff0c;將目光聚焦于此。被第三方機…

qt使用camke時,采用vcpkg工具鏈設置VTK的qt模塊QVTKOpenGLNativeWidget

下載:QVTKOpenGLNativeWidget嵌入qt應用中資源-CSDN下載 1.通過vcpkg安裝VTK,目前的VTK里面默認為qt6,如果需要安裝qt5,需要將端口配置進行修改 筆者的vcpkg的vtk端口路徑:D:\vcpkg\ports\vtk portfile.cmake 修改點: #第一處 #file(READ "${CURRENT_INSTALLED_DIR}/sh…

Axios在鴻蒙應用開發中的使用

目錄一、簡介二、安裝與配置三、axios用法1.axios泛型參數(1).第三個泛型參數-約束data請求參數的類型(2).第二個泛型參數-決定后臺返回數據的類型2.axios攔截器3.請求工具封裝統一處理業務狀態碼錯誤統一處理401或404錯誤一、簡介 Axios 是一個基于 Promise 的網絡請求庫&…

第九周文件上傳

文件上傳漏洞 不同的網站要不同的webshell。我們使用是php開發的網站。 一服務器白名單繞過 服務端白名單(Whitelist)是?種安全機制&#xff0c;它只允許預定義的合法元素通過&#xff08;只有有限的元素進入&#xff09;&#xff0c;其他所有內容默認被拒絕。相比黑名單&am…

計算機視覺必讀論文:從經典到前沿

計算機視覺必讀論文:從經典到前沿 一、前言 二、經典論文解讀? 2.1 圖像分類? 2.1.1 《ImageNet Classification with Deep Convolutional Neural Networks》(AlexNet)? 2.1.2 《Very Deep Convolutional Networks for Large-Scale Image Recognition》(VGGNet)? 2.1.…

對比PowerBI的字段參數,QuickBI的已選字段還有改進的空間

對比PowerBI的字段參數&#xff0c;QuickBI的已選字段還有改進的空間 之前分享過QuickBI的已選字段 vs PowerBI的字段參數&#xff0c;QuickBI可以在表格中實現PowerBI的字段參數效果&#xff0c;甚至比PowerBI實現的過程和使用方式更絲滑。 但如果應用到圖形中會怎么樣呢&am…

飛算JavaAI:Java開發新時代的破曉之光

免責聲明&#xff1a;此文章的所有內容皆是本人實驗測評&#xff0c;并非廣告推廣&#xff0c;并非抄襲。如有侵權&#xff0c;請聯系&#xff0c;謝謝&#xff01;【#飛算JavaAl炫技賽】 【#Java開發】摘要&#xff1a;飛算JavaAI作為全球首款聚焦Java的智能開發助手&#xff…