【重新認識C語言----結構體篇】

目錄

-----------------------------------------begin-------------------------------------

引言

1. 結構體的基本概念

1.1 為什么需要結構體?

1.2 結構體的定義

2. 結構體變量的聲明與初始化

2.1 聲明結構體變量

2.2 初始化結構體變量

3. 結構體成員的訪問

3.1 使用點運算符(.)

3.2 結構體指針與箭頭運算符(->)

4. 結構體的內存布局

4.1 內存對齊規則

4.2 手動控制內存對齊

5. 結構體的高級用法

5.1 結構體數組

5.2 嵌套結構體

5.3 結構體與函數

5.4 使用typedef簡化結構體類型名

6. 結構體與聯合體(Union)的區別

7. 綜合示例:學生管理系統

8. 常見問題與注意事項

結語

路過的佬們點點關注哦~

你們的鼓勵是我前進的動力~

-------------------------------------------end-------------------------------------


-----------------------------------------begin-------------------------------------

引言

在C語言編程中,結構體(Structure)?是一種非常重要的復合數據類型。它允許開發者將多個不同類型的變量組合成一個邏輯單元,從而更高效地管理復雜數據。無論是實現鏈表、樹等數據結構,還是描述現實世界中的實體(如學生、商品等),結構體都扮演著核心角色。本文將詳細講解結構體的定義、使用及高級特性,幫助讀者徹底掌握這一關鍵概念。


1. 結構體的基本概念

1.1 為什么需要結構體?

假設我們需要描述一個學生的信息,包括姓名(字符串)、學號(整數)、年齡(整數)和成績(浮點數)。如果單獨使用多個變量來存儲這些信息,代碼會變得冗長且難以維護。例如:

char name[20];
int id;
int age;
float score;

結構體可以將這些變量封裝為一個整體,使數據管理更加清晰。

1.2 結構體的定義

結構體通過?struct?關鍵字定義,語法如下:

struct 結構體名 {數據類型 成員1;數據類型 成員2;// ...
};

示例:定義一個學生結構體

struct Student {char name[20];int id;int age;float score;
};

2. 結構體變量的聲明與初始化

2.1 聲明結構體變量

結構體定義后,可以通過兩種方式聲明變量:

  1. 在定義結構體時直接聲明變量

    struct Student {// 成員定義
    } stu1, stu2;  // 直接聲明變量stu1和stu2

  2. 通過結構體類型名聲明變量

    struct Student stu3;  // 聲明一個Student類型的變量stu3

    2.2 初始化結構體變量

    結構體變量可以在聲明時初始化,或通過賦值操作初始化。
    示例:

// 聲明時初始化
struct Student stu1 = {"Alice", 1001, 18, 90.5};// 單獨賦值初始化
struct Student stu2;
strcpy(stu2.name, "Bob");
stu2.id = 1002;
stu2.age = 19;
stu2.score = 85.0;

3. 結構體成員的訪問

3.1 使用點運算符(.

通過?.?運算符可以直接訪問結構體變量的成員:

printf("學生姓名:%s\n", stu1.name);
printf("學號:%d\n", stu1.id);

3.2 結構體指針與箭頭運算符(->

如果通過指針訪問結構體成員,需使用?->?運算符:

struct Student *pStu = &stu1;
printf("年齡:%d\n", pStu->age);  // 等價于 (*pStu).age

4. 結構體的內存布局

4.1 內存對齊規則

為了提高內存訪問效率,結構體的成員在內存中遵循對齊規則:

  • 對齊數(Alignment):成員的大小與編譯器默認對齊數中的較小值。

  • 起始地址:每個成員的起始地址必須是對齊數的整數倍。

  • 總大小:結構體的總大小是對齊數最大值的整數倍。

示例:

struct Example {char c;     // 1字節,對齊數為1int i;      // 4字節,對齊數為4double d;   // 8字節,對齊數為8
};

內存布局分析:

  • char c?占1字節,起始地址0。

  • int i?對齊數為4,起始地址需是4的倍數,因此填充3字節(地址1~3),起始地址4。

  • double d?對齊數為8,起始地址8。
    總大小 = 1 + 3(填充) + 4 + 8 = 16字節。

4.2 手動控制內存對齊

通過?#pragma pack(n)?可以修改默認對齊數(n為1、2、4、8等):

#pragma pack(1)  // 設置為1字節對齊
struct PackedExample {char c;int i;double d;
};
#pragma pack()   // 恢復默認對齊

此時結構體總大小為 1 + 4 + 8 = 13字節。

5. 結構體的高級用法

5.1 結構體數組

結構體數組用于存儲多個相同類型的結構體變量。
示例:

struct Student students[3] = {{"Alice", 1001, 18, 90.5},{"Bob", 1002, 19, 85.0},{"Charlie", 1003, 20, 92.0}
};

5.2 嵌套結構體

結構體可以嵌套其他結構體作為成員。
示例:

struct Date {int year;int month;int day;
};struct Employee {char name[20];struct Date birthday;
};

5.3 結構體與函數

結構體可以作為函數參數或返回值傳遞。
示例:

// 函數參數:按值傳遞
void printStudent(struct Student stu) {printf("姓名:%s\n", stu.name);
}// 函數參數:按指針傳遞(推薦,避免內存拷貝)
void updateScore(struct Student *pStu, float newScore) {pStu->score = newScore;
}// 函數返回結構體
struct Student createStudent() {struct Student stu = {"David", 1004, 21, 88.5};return stu;
}

5.4 使用typedef簡化結構體類型名

通過?typedef?可以為結構體定義別名,簡化代碼:

typedef struct Student {// 成員定義
} Student;  // 別名// 聲明變量
Student stu4;

6. 結構體與聯合體(Union)的區別

結構體與聯合體(union)的區別在于內存分配方式:

  • 結構體:每個成員擁有獨立的內存空間,總大小為所有成員大小之和(考慮對齊)。

  • 聯合體:所有成員共享同一塊內存空間,總大小等于最大成員的大小。

7. 綜合示例:學生管理系統

#include <stdio.h>
#include <string.h>typedef struct Student {char name[20];int id;float score;
} Student;void printStudent(const Student *stu) {printf("姓名:%s\t學號:%d\t成績:%.1f\n", stu->name, stu->id, stu->score);
}int main() {Student students[3];// 輸入學生信息for (int i = 0; i < 3; i++) {printf("輸入第%d個學生的姓名、學號和成績:", i+1);scanf("%s %d %f", students[i].name, &students[i].id, &students[i].score);}// 輸出學生信息printf("\n學生列表:\n");for (int i = 0; i < 3; i++) {printStudent(&students[i]);}return 0;
}

8. 常見問題與注意事項

  • 結構體賦值

    結構體變量可以直接賦值給同類型的變量(按值拷貝):

Student stu1 = {"Alice", 1001, 90.5};
Student stu2 = stu1;  // 合法,內存拷貝
  • 結構體大小計算

    使用?sizeof?運算符獲取結構體大小,但需注意內存對齊的影響。

  • 結構體與動態內存分配

    結構體指針可以結合?malloc?實現動態內存分配:

Student *pStu = (Student*)malloc(sizeof(Student));
free(pStu);

結語

結構體是C語言中組織復雜數據的核心工具,其靈活性和高效性使其在系統編程、嵌入式開發等領域廣泛應用。通過本文的學習,讀者應能夠熟練定義、操作結構體,并理解其底層內存布局。建議結合實際項目練習,進一步鞏固這一重要概念。

路過的佬們點點關注哦~
你們的鼓勵是我前進的動力~

-------------------------------------------end-------------------------------------

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

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

相關文章

如何在Vscode中接入Deepseek

一、獲取Deepseek APIKEY 首先&#xff0c;登錄Deepseek官網的開放平臺&#xff1a;DeepSeek 選擇API開放平臺&#xff0c;然后登錄Deepseek后臺。 點擊左側菜單欄“API keys”&#xff0c;并創建API key。 需要注意的是&#xff0c;生成API key復制保存到本地&#xff0c;丟失…

電腦開機提示按f1原因分析及終極解決方法來了

經常有網友問到一個問題&#xff0c;我電腦開機后提示按f1怎么解決&#xff1f;不管理是臺式電腦&#xff0c;還是筆記本&#xff0c;都有可能會遇到開機需要按F1&#xff0c;才能進入系統的問題&#xff0c;引起這個問題的原因比較多&#xff0c;今天小編在這里給大家列舉了比…

AI協助探索AI新構型自動化創新的技術實現

一、AI自進化架構的核心范式 1. 元代碼生成與模塊化重構 - 代碼級自編程&#xff1a;基于神經架構搜索的強化學習框架&#xff0c;AI可通過生成元代碼模板&#xff08;框架的抽象層定義、神經元結點-網絡拓撲態的編碼抽象定義&#xff09;自動組合功能模塊。例如&#xff0…

RAID獨立硬盤冗余陣列

目錄 一、RAID基本功能 二、RAID常見級別 三、實現方式 1、軟件磁盤陣列 2、硬件磁盤陣列 四、熱備盤 RAID&#xff08;Redundant Array of Independent Disks&#xff09;是一種通過將多個硬盤組合成一個邏輯單元來提升存儲性能、冗余性或兩者兼具的技術。 一、RAID基本…

【高級篇 / IPv6】(7.2) ? 04. 在60E上配置ADSL撥號寬帶上網(IPv4) ? FortiGate 防火墻

【簡介】除了單位用戶以外&#xff0c;大部分個人用戶目前使用的仍然是30E、50E、60E系列防火墻&#xff0c;固件無法達到目前最高版本7.6&#xff0c;這里以最常用的60E為例&#xff0c;演示固件版本7.2下實現ADSL撥號寬帶的IPv6上網。由于內容比較多&#xff0c;文章分上、下…

Qt之設置QToolBar上的按鈕樣式

通常給QAction設置icon后,菜單欄的菜單項和工具欄(QToolBar)上對應的按鈕會同時顯示該icon。工具欄還可以使用setToolButtonStyle函數設置按鈕樣式,其參數為枚舉值: enum ToolButtonStyle {ToolButtonIconOnly,ToolButtonTextOnly,ToolButtonTextBesideIcon,ToolButtonTe…

【從零開始系列】DeepSeek-R1:(本地部署使用)思維鏈推理大模型,開源的神!——Windows/Linux本地環境測試 + vLLM遠程部署服務

目錄 一、環境配置 1.硬件設備評估 2.基礎環境安裝 3.模型參數下載 (1) huggingface鏡像源下載 (2) modelscope魔搭社區下載 &#xff08;推薦&#xff09; 二、基礎使用&#xff08;Linux、Window兼容&#xff09; 1.Transformers庫自編代碼 三、進階使用&#xff08;僅Lin…

DeepSeek 開源模型全解析(2024.1.1–2025.2.6)

目錄 一、通用大語言模型&#xff1a;DeepSeek-V3 系列 137 二、推理優化模型&#xff1a;DeepSeek-R1 系列 811 三、多模態模型&#xff1a;Janus 系列 10 四、生態整合與部署建議 五、總結與展望 以下為 DeepSeek 在 2024 年 1 月至 2025 年 2 月期間發布的開源模型及其…

Mac: docker安裝以后報錯Command not found: docker

文章目錄 前言解決辦法&#xff08;新的&#xff09;解決步驟&#xff08;原來的&#xff09;不推薦總結 前言 ?本操作參考 http://blog.csdn.net/enhenglhm/article/details/137955756 原作者&#xff0c;更詳細請&#xff0c;查看詳細內容請關注原作者。 一般&#xff0c;…

《手札·開源篇》數字化轉型助力永磁電機企業降本增效:快速設計軟件如何讓研發效率提升40%?

數字化轉型助力永磁電機企業降本增效&#xff1a;快速設計軟件如何讓研發效率提升40%&#xff1f; 一、痛點&#xff1a;傳統研發模式正在吃掉企業的利潤 永磁電機行業面臨兩大挑戰&#xff1a; 研發周期長&#xff1a;一款新電機從設計到量產需6-12個月&#xff0c;電磁計算…

0207作業

思維導圖 服務器 enum Type{TYPE_REGIST,TYPE_LOGIN };typedef struct Pack{int size;enum Type type;char buf[2048];}pack_t;typedef struct list{union Data{struct List* tail;char str[64];}data;struct List* next;struct List* prev; }List;List* create_node(){List* …

深入淺出 DeepSeek V2 高效的MoE語言模型

今天&#xff0c;我們來聊聊 DeepSeek V2 高效的 MoE 語言模型&#xff0c;帶大家一起深入理解這篇論文的精髓&#xff0c;同時&#xff0c;告訴大家如何將這些概念應用到實際中。 &#x1f31f; 什么是 MoE&#xff1f;——Mixture of Experts&#xff08;專家混合模型&#x…

RabbitMQ 從入門到精通:從工作模式到集群部署實戰(五)

#作者&#xff1a;閆乾苓 系列前幾篇&#xff1a; 《RabbitMQ 從入門到精通&#xff1a;從工作模式到集群部署實戰&#xff08;一&#xff09;》&#xff1a;link 《RabbitMQ 從入門到精通&#xff1a;從工作模式到集群部署實戰&#xff08;二&#xff09;》&#xff1a; lin…

nodejs:express + js-mdict 網頁查詢英漢詞典,能播放.spx 聲音

向 DeepSeek R1 提問&#xff1a; 我想寫一個Web 前端網頁&#xff0c;后臺用 nodejs js-mdict , 實現在線查詢英語單詞&#xff0c;并能播放.spx 聲音文件 1. 項目結構 首先&#xff0c;創建一個項目目錄&#xff0c;結構如下&#xff1a; mydict-app/ ├── public/ │ …

Linux ftrace 內核跟蹤入門

文章目錄 ftrace介紹開啟ftraceftrace使用ftrace跟蹤指定內核函數ftrace跟蹤指定pid ftrace原理ftrace與stracetrace-cmd 工具KernelShark參考 ftrace介紹 Ftrace is an internal tracer designed to help out developers and designers of systems to find what is going on i…

【抽象代數】1.1. 運算及關系

集合與映射 定義1. 設 為 的子集&#xff0c;定義 到 的映射 &#xff1a; 使得 &#xff0c;稱 為 到 的嵌入映射。 定義2. 設 為 的子集&#xff0c; 為 到 的映射&#xff0c; 為 到 的映射&#xff0c;如果 &#xff0c;稱為的開拓&#xff0c; 為 的限制&…

pytest+request+yaml+allure 接口自動化測試全解析[手動寫的跟AI的對比]

我手動寫的:Python3:pytest+request+yaml+allure接口自動化測試_request+pytest+yaml-CSDN博客 AI寫的:pytest+request+yaml+allure 接口自動化測試全解析 在當今的軟件開發流程中,接口自動化測試扮演著至關重要的角色。它不僅能夠提高測試效率,確保接口的穩定性和正確性…

數據庫高安全—審計追蹤:傳統審計統一審計

書接上文數據庫高安全—角色權限&#xff1a;權限管理&權限檢查&#xff0c;從權限管理和權限檢查方面解讀了高斯數據庫的角色權限&#xff0c;本篇將從傳統審計和統一審計兩方面對高斯數據庫的審計追蹤技術進行解讀。 4 審計追蹤 4.1 傳統審計 審計內容的記錄方式通…

第三個Qt開發實例:利用之前已經開發好的LED驅動在Qt生成的界面中控制LED2的亮和滅

前言 上一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145459006 中&#xff0c;我們是直接利用GPIO子系統控制了LED2的亮和滅&#xff0c;這篇博文中我們利用之前寫好的LED驅動程序在Qt的生成的界面中控制LED2的亮和滅。 之前已經在下面兩篇博文中實現了LED驅動…

deepseek來講lua

Lua 是一種輕量級、高效、可嵌入的腳本語言&#xff0c;廣泛應用于游戲開發、嵌入式系統、Web 服務器等領域。以下是 Lua 的主要特點和一些基本概念&#xff1a; 1. 特點 輕量級&#xff1a;Lua 的核心非常小&#xff0c;適合嵌入到其他應用程序中。高效&#xff1a;Lua 的執…