struct結構體、union聯合體和枚舉

目錄

一、結構體的聲明和使用

1.1 結構體正常聲明和創建

1.2 結構體特殊聲明

1.3 結構體的自引用

二、結構體內存對齊

2.1 對齊規則

2.2 #pragma修改

三、結構體傳參

四、結構體位段

4.1 位段內存分配

4.2 位段內存應用

五、結構體中的柔性數組概念

六、union聯合體

6.1 union聯合體聲明、使用和特點

6.2 union聯合體在內存的存儲

七、枚舉類型

7.1 枚舉類型的聲明

7.2 枚舉類型的優點


一、結構體的聲明和使用

1.1 結構體正常聲明和創建

????????struct用來聲明結構體變量,格式為struct 名字{內部成員};(這里有分號)后面還能直接設置全局變量,直接寫變量名,比如struct Stu{};然后初始化一個變量名struct Stu s1,這個s1就是結構變量(struct Stu是一個結構體的類型是一個整體,而s1是這個變量名)。使用時需要使用{}里面用來設置初始化的,如果struct里面還有一個結構體,那么初始化時{}這個括號內也要再加一個括號給他初始化,引用時可以不按順序來設置初始化,這時候就需要一個操作符“.”點這個操作符,格式為.內部變量名=初始化。當然還可以修改初始化內容就是結構體名.內部變量名=修改內容,但是數組就需要一個庫函數strcpy(string.h),strcpy(結構體名.內部變量,修改內容)對于內部成員為指針,引用時可以用“->”指針取向操作符。

1.2 結構體特殊聲明

? ? ? ? 對于特殊聲明就是沒有名字(指的是結構體名字),而如果沒有名字的結構體內成員是一模一樣的兩個結構體,兩個結構體中設置指針,將一個指針賦給另一個結構體的指針時,編譯器會報警告(編譯器默認這兩個結構體指針類型是不一樣的)。

#include<stdio.h>
struct
{char str[20];int a;char b;
}*s1,a;
struct
{char str[20];int a;char b;
}*s2;
int main()
{s1 = &a;s2 = s1;return 0;
}

?報警告!!!

匿名的結構體類型,如果沒有對結構體類型重命名的話,基本上只能使??次。

1.3 結構體的自引用

? ? ? ? 結構體的自引用就是鏈表,通過指針引用結構體進行內容訪問尋找數據。

? ? ? ? 需要定義鏈表的節點

struct Stu
{char name[20];//數據域struct Stu* nest;//地址域
};

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??? ↑↑↑

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ????????????????????????正確方式?

struct Stu
{char name[20];struct Stu nest;
};

????????????????????????????????????????????????????????????????? ↑↑↑

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 錯誤方式

擴展:數據結構,是描述數據在內存中的存儲結構。結構體鏈表(結構體自引用),通過相同的節點進行連接,上一個節點有下一個節點的地址,而下個節點有下下個節點的地址。

????????這里夾雜了 typedef 對匿名結構體類型重命名?,在函數中自引用如果使用不到位會報錯,不能只寫重命名的名字到里面,而是要寫全,才能設置為指針域。

#include<stdio.h>
typedef struct node
{int a;//node* next;//因為上面typedef重命名還沒命名完,所以這里需要寫全struct node* nest;//所以還需要自己來寫
}node;//這里typedef已經重定義完了int main()
{return 0;
}

?

二、結構體內存對齊

2.1 對齊規則

? ? ? ? 第一條:結構體內部的第一個任何成員是在偏移量為0位置

? ? ? ? 第二條:結構體要對齊到最小對齊數的整數倍(最近的整數倍);最小對齊數為成員類型的字節數與編譯器默認的對齊數的最小對齊數。這里以我的編譯器vs來舉例,該編譯器的默認為8,我在結構體內部用了一個char一個int類型成員(按左到右按順序)按照第一條char位于偏移量為0,而int類型的話,那就是要位于偏移量為4的位置了(int類型4個字節,默認8,最小為4)。

? ? ? ? 第三條:結構體總大小要為最大對齊數(這里指的是成員內最大對齊數,char最小是1,int最小是4,所以最大對齊數為4)的整數倍(最近)。同樣的舉一個例子來說明 內部有三個成員(按順序)char、int和char類型的成員

? ? ? ? 第四條:嵌套結構體時,計算結構體總大小時,最大對齊數要和嵌套結構體的內部成員一起計算,嵌套結構體時可以將嵌套的那個結構體當作結構體內的一個成員,規則都和前面3條符號,就是計算總大小時的最大對齊數要配合嵌套結構體的內部成員。

#include<stdio.h>
struct test1
{char a;double b;char c;int d;
};
struct test2
{int e;struct test1;//默認8,這個成員字節為24,最小為8
};
int main()
{printf("%zd\n", sizeof(struct test2));return 0;
}

?

?對于結構體的內存對齊一般是為了用空間換取時間的手段,方便了內存的讀取(如果不對齊,可能需要讀取兩次,對齊只需讀一次),提高讀取效率,不過在對于這個規則,我們不能一味的用大量的空間去換取時間,可以將一些小的類型寫在一起(相同類型),避免了大量空間的浪費,也確保了讀取效率。

計算偏移量,一般用offsetof來表示宏,可計算結構體成員相較于結構體起始位置的偏移量,他需要頭文件stddef.h。用法為offsetof(結構體類型,結構體內成員)?。

2.2 #pragma修改

? ? ? ? 這個定義是用于改變默認對齊數的(改變的是編譯器),一般編譯器默認是8,改變為4或者2,也會影響結構體大小。

這里pragma要配合pack使用。不過一般修改都是以2的次方數進行修改的。?

三、結構體傳參

? ? ? ? 結構體傳參有兩種方式,一種是傳值(結構體變量),一種是傳址(傳地址)。

#include<stdio.h>
struct Stu
{char name[20];int age;
};
void print2(struct Stu* s1)//傳址
{printf("%s\n", s1->name);
}
void print1(struct Stu s1)//傳值
{printf("%s\n", s1.name);
}
int main()
{struct Stu s1 = { "zhangsan",20 };print1(s1);print2(&s1);return 0;
}

????????一般我們寫結構體的時候會選擇傳址調用,傳值調用消耗內存太大了,如果結構體內部有一個很大的數組,那么這個結構體開辟空間會很大,不僅如此形參和實參的調用都會開辟這么多空間。傳值調用,因為指針字節要么是4個字節要么是8個字節,就算開辟也不會占很大空間,所以一般會使用傳址調用。

四、結構體位段

4.1 位段內存分配

? ? ? ? 結構體位段,用于節省空間方便傳輸等。結構體內的成員必須是int、unsigned int、signed int類型,不過在c99中其他成員類型也是可以。

struct A
{int a : 2;int b : 5;int c : 10;int d : 30;
};

????????這就是一個位段,后面接的是比特數?

? ? ? ? 內存中的位段是

這里如果以上空間都正常使用的話,一共開辟2個字節空間,但是實際不是這樣,因為他們不夠連續在一起,就會再開辟(因為不是從左到右,這里是從右到左)?

4.2 位段內存應用

? ? ? ? ????????位段在網絡傳輸過程中用到很多位段,因為我們在傳輸的時候會考慮到傳輸速度和簡單方面考慮可以類比卡車。

像第二張,這種小車就能夠進行超車,效率會很快。

位段是沒有跨平臺性的,所以我們可以為一個平臺專門設置位段進行節約空間。,不過位段也有缺點,就是不能取地址嗎,所以就不能通過scanf來修改內的內容,只能先賦值在位段

五、結構體中的柔性數組概念

? ? ? ? 柔性數組是位于結構體內最后的一位成員的數組,可以沒有大小。特點就是計算結構體總大小時,不會計算數組大小,這個柔性數組是可以通過動態內存來確定數組大小(更加靈活),這個我后面會和動態內存一起講。

六、union聯合體

6.1 union聯合體聲明、使用和特點

? ? ? ? union聯合體聲明和時候方法是和struct結構體是一樣的,也有匿名聯合體,唯一的區別就是在計算時總大小時是不一樣的,union聯合體大小是去內部成員內最大字節,其他的會重疊內存,改變一個字節就會影響另一個數。聯合體相比結構體會更加節約空間。

//在表示商品共同屬性和特殊屬性時也可以使用union聯合體
#include<stdio.h>
struct gift_list
{int stock_number;//庫存double price;//定價int item_type;//商品類型union{struct{char tille[20];//書名char author[20];//作者名int num_pages;//頁數}book;struct{char design[20];//設計}mug;struct{char design[20];//設計int colors;//顏色int sizes;//尺寸}shirt;};//這里都用匿名,是因為都只使用一次
}item;
//這樣的設計就能節約空間(相比較全部用struct結構體)
int main()
{return 0;
}

6.2 union聯合體在內存的存儲

? ? ? ? union聯合體在內存中是內存重疊。

????????這里用判斷大小端來舉例

#include<stdio.h>
union A
{char a;int b;
};
int check_sys()
{union A n = { 0 };n.b = 1;if (n.a == 1){return 1;}else{return 0;}
}
int main()
{int ret =check_sys();if (ret == 1){printf("小端\n");}else{printf("大端\n");}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;
}

七、枚舉類型

7.1 枚舉類型的聲明

????????枚舉一般用于列舉,比如生活中的星期、性別、月份和三原色等。聲明和使用和結構體和聯合體類似。

enum sex
{boy,girl,secret
};//格式和結構體和

內部的值都是枚舉常量,只能在內部改變。內部不賦值,那就默認從0開始遞增。

7.2 枚舉類型的優點

? ? ? ? 枚舉的優點1.方便代碼可讀性,可維護性。2.相較于用#define定義的常量,枚舉有類型的會更加嚴謹。3.使用方便,可以一次性列舉多個常量。4.枚舉是遵循定義域的,在函數中定義,就只能在函數中使用

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

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

相關文章

大模型本地部署系列(2) Ollama部署DeepSeek-R1

成功運行截圖 部署步驟 我們進入到ollama的官網&#xff1a; Ollama?ollama.com/?編輯 找到上方的Models &#xff0c;然后點擊 此時會跳轉到模型列表頁面&#xff1a; 點擊 deepseek-r1 鏈接進去&#xff0c;此時我們會看到下拉框中有各個版本的大模型&#xff0c;越往后…

繪制動態甘特圖(以流水車間調度為例)

import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np from matplotlib import cm# 中文字體配置&#xff08;必須放在所有繪圖語句之前&#xff09; plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] Fa…

PyTorch實現線性回歸的基礎寫法與封裝API寫法

目錄 1. 基礎寫法 1.1導包 2.2加載讀取數據 2.3原始數據可視化(畫圖顯示) 2.4線性回歸的(基礎)分解寫法 2.5定義訓練過程 2.PyTorch實現 線性回歸的封裝寫法(實際項目中的常用寫法) 2.1創建線性回歸模型 2.2定義損失函數 2.3定義優化器 2.4定義訓練過程 1…

python 常用的6個爬蟲第三方庫

Python中有非常多用于網絡數據采集的庫&#xff0c;功能非常強大&#xff0c;有的用于抓取網頁&#xff0c;有的用于解析網頁&#xff0c;這里介紹6個最常用的庫。 1. BeautifulSoup BeautifulSoup是最常用的Python網頁解析庫之一&#xff0c;可將 HTML 和 XML 文檔解析為樹形…

基于BP神經網絡的雜草智能識別系統(雜草識別、Python項目)

基于BP神經網絡的雜草智能識別系統 項目介紹 本項目是一個基于PyQt5和BP神經網絡的雜草智能識別系統。系統通過圖像處理和神經網絡技術&#xff0c; 能夠識別8種不同的雜草類別。用戶可以通過上傳圖片&#xff0c;系統會自動識別圖片中的雜草類別&#xff0c;并顯示識別結果和…

Python3筆記之號稱替代pip的uv包管理器

uv是什么&#xff1f; uv&#xff0c;這是一個由 Astral 團隊開發的極快速的Python包和項目管理工具&#xff0c;用Rust語言編寫。它集成了多種功能&#xff0c;旨在替代pip、pip-tools、pipx、poetry、pyenv、twine、virtualenv等多個工具&#xff0c;提供更高效、更全面的Py…

IT管理思路

甲方CIO和IT管理者-如何做好組織級IT能力提升_嗶哩嗶哩_bilibili

ChatGPT的GPT-4o創建圖像Q版人物提示詞實例展示

最近感覺GPT-4o發布的新功能真的強大&#xff0c;所以總結了一些提示詞分享給大家&#xff0c;大家可以去試試&#xff0c;玩法多多&#xff0c;可以用GPT-4o生成圖片&#xff0c;然后用可靈進行圖生視頻&#xff0c;就能去發布視頻了&#xff01;接下來和筆者一起來試試&#…

Transformer Decoder Block的幾個優化方案

寫在前面 在大型語言模型(LLM)的演進浪潮中,Transformer 架構憑借其強大的并行計算能力和對長距離依賴的出色捕捉,奠定了核心地位。然而,標準的 Transformer Decoder Block 遵循著一種相對固定的模式:先進行自注意力(Self-Attention)捕捉上下文信息,再通過前饋神經網…

五種IO模型與select和poll分別實現多路轉接

五種IO模型與select和poll分別實現多路轉接 何為IO 不論是在前面文件部分&#xff0c;還是后面的網絡部分&#xff0c;IO都是非常常見的。但是當時只是簡單對IO進行提及&#xff0c;并沒有對IO的本質進行介紹。那么到底何為IO&#xff1f;IO全稱為輸入和輸出&#xff0c;而任…

單例模式的寫法(保證線程安全)

1. 引言 1.1 什么是單例模式&#xff1f; 單例模式&#xff08;Singleton Pattern&#xff09;是一種創建型設計模式&#xff0c;它確保一個類只有一個實例&#xff0c;并提供一個全局訪問點。 核心思想&#xff1a;控制實例化過程&#xff0c;避免重復創建對象。 1.2 為什么…

C++ 環境設置

C++ 環境設置 引言 C++作為一種高性能的編程語言,廣泛應用于系統軟件、游戲開發、實時系統等領域。為了能夠順利進行C++編程,我們需要在計算機上配置合適的開發環境。本文將詳細講解如何在Windows、macOS和Linux系統中設置C++開發環境。 Windows系統下C++環境設置 1. 安裝…

【Kafka基礎】ZooKeeper在Kafka中的核心作用:分布式系統中樞神經系統

在分布式系統的世界里&#xff0c;協調和管理多個節點間的狀態是一項復雜而關鍵的任務。Apache Kafka作為一款高性能的分布式消息系統&#xff0c;其設計哲學是"專為單一目的而優化"——即高效處理消息流。為了實現這一目標&#xff0c;Kafka選擇將集群協調管理的重任…

<《AI大模型應知應會100篇》第8篇:大模型的知識獲取方式及其局限性

第8篇&#xff1a;大模型的知識獲取方式及其局限性 摘要 大模型&#xff08;如GPT、BERT、Qwen、DeepSeek等&#xff09;憑借其卓越的自然語言處理能力&#xff0c;已經成為人工智能領域的明星。然而&#xff0c;這些模型“知道”什么&#xff1f;它們如何獲取知識&#xff1f…

ESModule和CommonJS在Node中的區別

ESModule console.log(require);//>errorconsole.log(module);//>errorconsole.log(exports);//>errorconsole.log(__filename);//>errorconsole.log(__dirname);//>error全部報錯commonjs console.log(require);console.log(module);console.log(exports);co…

Spring Boot 配置文件加載優先級全解析

精心整理了最新的面試資料和簡歷模板&#xff0c;有需要的可以自行獲取 點擊前往百度網盤獲取 點擊前往夸克網盤獲取 Spring Boot 配置文件加載優先級全解析 Spring Boot 的配置文件加載機制是開發者管理不同環境配置的核心功能之一。其通過外部化配置&#xff08;Externaliz…

2025 年陜西消防設施操作員考試攻略:歷史文化名城的消防傳承與創新?

陜西擁有豐富的歷史文化遺產&#xff0c;眾多古建筑分布其中&#xff0c;同時也在不斷推進現代化建設&#xff0c;消防工作面臨傳承與創新的雙重任務&#xff0c;這在考試中也有所體現。? 考點融合與特色&#xff1a;一方面&#xff0c;古建筑的消防保護是重點&#xff0c;包…

【Unity網絡編程知識】C#的 Http相關類學習

1、搭建HTTP服務器 使用別人做好的HTTP服務器軟件&#xff0c;一般作為資源服務器時使用該方式&#xff08;學習階段建議使用&#xff09;自己編寫HTTP服務器應用程序&#xff0c;一般作為Web服務器或者短連接游戲服務器時使用該方式&#xff08;工作后由后端程序員來做&#…

Android Studio - 解決 Please Select Android SDK

一、出現的問題 點擊 Run 后彈窗&#xff0c;圖一位置出現圖二提示。 二、解決辦法 進入 Tools -> SDK Manager&#xff0c;在 Android SDK Location 點擊 Edit&#xff0c;一直 Next 就解決了。

UE5學習筆記 FPS游戲制作44 統一UI大小 sizeBox

如果我們希望多個類似的UI大小一樣&#xff0c;例如不同菜單的標題&#xff0c;可以使用sizeBox組件 我們在標題控件上&#xff0c;用sizeBox包裹所有子物體 然后指定他的最小寬高&#xff0c;或最大寬高 如果指定的是最小寬高&#xff0c;當子元素&#xff08;如圖片&#xf…