C語言結構體深入解析【結構體嵌套結構體,結構體變量和指針,結構體和函數,計算結構體大小,結構體數組,結構體成員的訪問,結構體與聯合】

C語言結構體深入解析

目錄

  • C語言結構體深入解析
    • 前言
    • 結構體的定義
    • 結構體在內存中的表示
    • 結構體變量初始化
      • 直接定義并初始化
      • 使用自己定義的結構體變量初始化新變量
      • 結構體數組初始化
    • 結構體中嵌套結構體
    • 結構體成員訪問
      • 點操作符(`.`)
      • 箭頭操作符(`->`)
    • 結構體變量和指針
      • 結構體指針定義與初始化
        • 動態分配內存
        • 比較與應用場景
    • 結構體和函數
      • 結構體作為函數參數
      • 結構體指針作為函數參數
      • 結構體作為函數返回值
      • 動態分配結構體并在函數中使用
    • 結構體與數組
      • 結構體數組
      • 結構體中嵌套數組
      • 結構體指針數組
    • 計算結構體大小
      • 計算結構體大小步驟:
        • 查看結構體大小
    • 結構體與聯合
    • 結語

前言

在C語言編程的世界里,結構體(struct)是一種復合數據類型,它允許你將不同類型的數據組合在一起,形成一個單一的復雜實體。這種特性極大地豐富了C語言處理現實世界問題的能力,特別是在設計復雜的數據結構和實現面向對象編程概念時。本文旨在深入探討C語言中的結構體,包括其定義、使用場景、內存布局、對齊規則、以及高級應用技巧。

結構體的定義

結構體通過struct關鍵字來定義,基本形式如下:

struct 結構體名{成員列表(基本數據類型、指針、數組或其他結構體類型)
}

例如 定義一個學生結構體
C語言結構體深入解析

結構體在內存中的表示

C語言結構體深入解析

結構體變量初始化

直接定義并初始化

C語言結構體深入解析

使用自己定義的結構體變量初始化新變量

您可以使用已定義的結構體變量來初始化同類的新結構體變量。這是通過簡單的賦值操作完成的,因為結構體變量之間可以整體賦值,只要它們是同一種結構體類型。
C語言結構體深入解析
輸出結果:
C語言結構體深入解析

結構體數組初始化

結構體數組的初始化可以通過直接在定義結構體數組時賦予初始值來完成
C語言結構體深入解析
輸出結果:
C語言結構體深入解析

結構體中嵌套結構體

結構體(struct)同樣支持嵌套使用,即在一個結構體中定義另一個結構體類型的成員。這種特性對于組織復雜的數據結構特別有用,可以讓數據更加模塊化和層次化。
案例:假設我們有兩個結構體,一個表示人(Person),另一個表示地址(Address
C語言結構體深入解析
輸出結果:
C語言結構體深入解析

結構體成員訪問

點操作符(.)

是最直接的方式,用于訪問結構體變量的成員。比如定義一個表示學生的結構體,包含姓名(name)和年齡(age)兩個成員:
C語言結構體深入解析
輸出結果:
C語言結構體深入解析

箭頭操作符(->)

訪問結構體成員:當你有一個指向結構體的指針時,可以使用箭頭操作符(->)來訪問該結構體的成員。處理結構體數組、動態分配的結構體或通過函數傳遞結構體指針等場景中非常有用。下面是使用箭頭操作符訪問結構體成員的一個示例:
C語言結構體深入解析
輸出結果
C語言結構體深入解析
在這個例子中,我們使用malloc函數動態分配了Student結構體的內存,并將返回的指針存儲在studentPtr中。之后,我們使用箭頭操作符(->)來訪問和修改結構體成員,如studentPtr->namestudentPtr->age。這種方式與之前使用點操作符直接訪問結構體成員的語法相似,但適用于結構體指針的情況。最后,別忘了在不再需要時釋放通過malloc分配的內存。

結構體變量和指針

結構體是一種復合數據類型,允許你組合不同類型的多個數據項(成員)到一個單獨的實體中。結構體變量直接存儲結構體的所有成員,而結構體指針則存儲結構體變量的地址。

結構體指針定義與初始化

以下是結構體變量和指針的一些關鍵點和使用方法:
C語言結構體深入解析
輸出結果
C語言結構體深入解析

動態分配內存

結構體指針常用于動態地在堆上分配結構體實例的內存。
C語言結構體深入解析
輸出結果:
在這里插入圖片描述

比較與應用場景
  • 結構體變量適合于當結構體較小,或者結構體的生命周期與定義它的作用域相同的情況。
  • 結構體指針在處理大型結構體、動態內存分配、函數參數傳遞(尤其是需要修改結構體內容時)以及實現復雜數據結構(如鏈表、樹等)時更為靈活和高效。

結構體和函數

在C語言中,結構體與函數的結合使用非常常見,主要用于封裝數據和操作這些數據的函數。結構體可以作為函數的參數、返回值,也可以在函數內部定義和使用。

結構體作為函數參數

將結構體作為函數的參數,可以實現對結構體數據的操作封裝,增強代碼的模塊化和可讀性。
C語言結構體深入解析
C語言結構體深入解析

結構體指針作為函數參數

常見的作法是使用結構體指針作為函數參數,這樣可以避免賦值整個結構體的開銷,特別是結構體比較大時
C語言結構體深入解析
輸出結果:
C語言結構體深入解析

結構體作為函數返回值

雖然C語言允許結構體作為函數的返回值,但需要注意的是,如果結構體過大可能會導致棧溢出問題。小結構體或指針作為返回值比較常見。
C語言結構體深入解析
輸出結果
C語言結構體深入解析

動態分配結構體并在函數中使用

對于大型結構體或需要在函數間共享數據的情況,通常會動態非陪結構體,并通過指針傳遞和返回。
C語言結構體深入解析
輸出結果
C語言結構體深入解析

結構體與數組

c語言中,結構體和數組都是重要的數據結構,他們可以結合起來使用,以實現復雜的數據管理和操作。

結構體數組

結構體數組允許你創建一個數組,其中每個元素都是相同的結構體類型,這對于存儲一系列具有相同屬性的對象非常有用,比如存儲一組學生的記錄。
C語言結構體深入解析
輸出結果:
C語言結構體深入解析

結構體中嵌套數組

除了數組包含結構體外,結構體內部也可以嵌套數組,這再處理一些固定大小的數據集時很有用。
C語言結構體深入解析
輸出結果:
C語言結構體深入解析

結構體指針數組

有時候,可能需要一個數組來存儲指向結構體的指針,這在動態分配結構體或者需要靈活的重排數據的時候非常有用。
C語言結構體深入解析
在這里插入圖片描述

計算結構體大小

在C語言中,結構體(struct)的大小由其所有成員的大小以及各成員之間的內存對齊規則共同決定。結構體的大小至少要能容納其最大成員的大小,同時考慮到CPU訪問效率,結構體成員通常會按一定的字節邊界對齊。不同編譯器和平臺可能有不同的默認對齊規則,但通常情況下,結構體的大小會是其成員大小和對齊要求的某種整數倍。

計算結構體大小步驟:

  • 確定每個成員的大小:首先,確定結構體中每個成員的數據類型及其對應的大小(例如,int通常是4字節,char1字節等)。
  • 考慮對齊要求:根據編譯器和目標平臺的對齊規則,確定每個成員相對于結構體起始位置的偏移量。一般而言,成員會被放置在滿足其自然對齊要求的位置上,比如int類型的自然對齊通常是4字節邊界,double可能是8字節邊界。
  • 計算結構體總大小:結構體的總大小是最后一個成員的末尾到結構體起始位置的距離,同時確保這個總大小滿足最嚴格的對齊要求。如果最后一個成員后面還有未使用的空間以滿足對齊,這部分也會被計入結構體的總大小。

示例:

	struct Example {char a;      // 1字節int b;       // 通常4字節char c;      // 1字節};
  • char a1字節。
  • int b需要對齊到4字節邊界,因此在a之后可能會有3字節的填充(如果a之后直接跟b,則b不會在其自然邊界上對齊)。
  • char c再占1字節。
    最終,盡管數據內容只需6字節(1+4+1),但由于對齊要求,結構體的實際大小可能會是8字節(具體取決于編譯器的對齊策略,這里假設為了保持int b4字節對齊,在ab之間有3字節填充,加上c之后總共8字節,滿足最嚴格的4字節對齊)。
查看結構體大小

可以使用sizeof運算符來獲取特定結構體類型的大小,如:

printf("Size of struct Example: %zu\n", sizeof(struct Example));

這會直接輸出該結構體類型的字節大小。

結構體與聯合

結構體與聯合(union)都是復合數據類型,但聯合的所有成員共享同一塊內存區域,而結構體的每個成員都有獨立的內存空間。聯合在需要節省內存且只有一項成員有效的情景下使用。

結語

結構體作為C語言中的重要組成部分,為程序設計者提供了構建復雜數據模型的強大工具。理解其內存布局、對齊規則以及如何高效利用結構體指針,對于編寫高效、可維護的代碼至關重要。掌握結構體的高級應用,能進一步提升解決實際問題的能力,特別是在系統編程、網絡編程以及游戲開發等領域。希望本文能幫助你深化對C語言結構體的理解,并在實踐中靈活運用。

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

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

相關文章

TensorFlow代碼邏輯 vs PyTorch代碼邏輯

文章目錄 一、TensorFlow(一)導入必要的庫(二)加載MNIST數據集(三)數據預處理(四)構建神經網絡模型(五)編譯模型(六)訓練模型&#xf…

@RequestMapping屬性詳解及案例演示

RequestMapping源碼 Target({ElementType.TYPE, ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Documented Mapping public interface RequestMapping {String name() default "";AliasFor("path")String[] value() default {};AliasFor(&quo…

智能寫作與痕跡消除:AI在創意文案和論文去痕中的應用

作為一名AI愛好者,我積累了許多實用的AI生成工具。今天,我想分享一些我經常使用的工具,這些工具不僅能幫助提升工作效率,還能激發創意思維。 我們都知道,隨著技術的進步,AI生成工具已經變得越來越智能&…

簡單分享 for循環,從基礎到高級

1. 基礎篇:Hello, For Loop! 想象一下,你想給班上的每位同學發送“Hello!”,怎么辦?那就是for循環啦, eg:首先有個名字的列表,for循環取出,分別打印 names ["Alice", …

Apache APISIX 介紹

Apache APISIX 是一個動態、實時、高性能的云原生API網關,屬于Apache軟件基金會旗下的項目。以下是對Apache APISIX的詳細介紹: 一、基本概述 定義:Apache APISIX是一個提供豐富流量管理功能的云原生API網關。功能:包括負載均衡…

git出現Permission denied問題

Warning: Permanently added ‘icode.baidu.com,10.11.81.103’ (RSA) to the list of known hosts. Permission denied (baas,keyboard-interactive,publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the…

nodejs操作excel文件實例,讀取sheets, 設置cell顏色

本代碼是我幫客戶做的兼職的實例,涉及用node讀取excel文件,遍歷sheets,給單元格設置顏色等操作,希望對大家接活有所幫助。 gen.js let dir"D:\\武漢煙廠\\山東區域\\備檔資料\\銷區零售終端APP維護清單\\走訪檔案\\2024年6月…

Spring之事務失效的場景

Spring事務失效的場景 異常捕獲處理:自己處理了異常,沒有拋出。解決:手動拋出拋出檢查異常:配置rollbackFor屬性為Excetion非public方法導致事務失效,改為public 1、異常捕獲處理 示例: 張三1000元&#…

7月形勢分析-您下一步該如何做,才能走出困境?

馬上工程項目,再有三五天就要結束的了。即便推后也不會超過一周時間了。所以需要考慮將來干啥呢?  一方面就是繼續去濟寧做建筑工程的活。管吃住,但是因為至親之間,難免咋說呢,總之還是不太舒服的樣子。管事情多&…

bigNumber的部分使用方法與屬性

場景:最近做IoT項目的時候碰到一個問題,涉及到雙精度浮點型的數據范圍的校驗問題。業務上其實有三種類型:int、float和double類型三種。他們的范圍分別是: //int int: [-2147483648, 2147483647],//float float: [-3402823466385…

PHP7源碼結構

PHP7程序的執行過程 1.PHP代碼經過詞法分析轉換為有意義的Token; 2.Token經過語法分析生成AST(Abstract Synstract Syntax Tree,抽象語法樹); 3.AST生成對應的opcode,被虛擬機執行。 源碼結構&#xff1…

一切為了安全丨2024中國應急(消防)品牌巡展武漢站成功召開!

消防品牌巡展武漢站 6月28日,由中國安全產業協會指導,中國安全產業協會應急創新分會、應急救援產業網聯合主辦,湖北消防協會協辦的“一切為了安全”2024年中國應急(消防)品牌巡展-武漢站成功舉辦。該巡展旨在展示中國應急(消防&am…

qt QTreeView的簡單使用(多級子節點)

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);setWindowTitle("QTreeView的簡單使用");model new QStandardItemModel;model->setHorizontalHeaderLabels(QStringList() << "left&q…

【數據結構 - 時間復雜度和空間復雜度】

文章目錄 <center>時間復雜度和空間復雜度算法的復雜度時間復雜度大O的漸進表示法常見時間復雜度計算舉例 空間復雜度實例 時間復雜度和空間復雜度 算法的復雜度 算法在編寫成可執行程序后&#xff0c;運行時需要耗費時間資源和空間(內存)資源 。因此衡量一個算法的好壞&…

[leetcode]longest-arithmetic-subsequence-of-given-difference. 最長定差子序列

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int longestSubsequence(vector<int> &arr, int difference) {int ans 0;unordered_map<int, int> dp;for (int v: arr) {dp[v] dp[v - difference] 1;ans max(ans, dp[v]);}return ans…

Qt源碼分析:窗體繪制與響應

作為一套開源跨平臺的UI代碼庫&#xff0c;窗體繪制與響應自然是最為基本的功能。在前面的博文中&#xff0c;已就Qt中的元對象系統(反射機制)、事件循環等基礎內容進行了分析&#xff0c;并捎帶闡述了窗體響應相關的內容。因此&#xff0c;本文著重分析Qt中窗體繪制相關的內容…

ECharts 快速入門

文章目錄 1. 引入 ECharts2. 初始化 ECharts 實例3. 配置圖表選項4. 使用配置項生成圖表5. 最常用的幾種圖形5.1 柱狀圖&#xff08;Bar Chart&#xff09;5.2 折線圖&#xff08;Line Chart&#xff09;5.3 餅圖&#xff08;Pie Chart&#xff09;5.4 散點圖&#xff08;Scatt…

如何完成域名解析驗證

一&#xff1a;什么是DNS解析&#xff1a; DNS解析是互聯網上將人類可讀的域名&#xff08;如www.example.com&#xff09;轉換為計算機可識別的IP地址&#xff08;如192.0.2.1&#xff09;的過程&#xff0c;大致遵循以下步驟&#xff1a; 查詢本地緩存&#xff1a;當用戶嘗…

Linux內核 -- 多線程之完成量completion的使用

Linux Kernel Completion 使用指南 在Linux內核編程中&#xff0c;completion是一個用于進程同步的機制&#xff0c;常用于等待某個事件的完成。它提供了一種簡單的方式&#xff0c;讓一個線程等待另一個線程完成某項任務。 基本使用方法 初始化 completion結構需要在使用之…

順序串算法庫構建

學習賀利堅老師順序串算法庫 數據結構之自建算法庫——順序串_創建順序串s1,創建順序串s2-CSDN博客 本人詳細解析博客 串的概念及操作_串的基本操作-CSDN博客 版本更新日志 V1.0: 在賀利堅老師算法庫指導下, 結合本人詳細解析博客思路基礎上,進行測試, 加入異常彈出信息 v1.0補…