[C語言初階]結構體初階

在這里插入圖片描述

目錄

  • 一、結構體的聲明
  • 二、結構體的定義和初始化
  • 三、結構體成員訪問
  • 四、結構體傳參
  • 五、函數調用的參數壓棧(了解)

在C語言中,我們知道數組是一組相同類型元素的集合,而結構體則更為靈活,它允許我們將不同類型的數據組合在一起,形成一個新的復合數據類型。本文將帶你全面了解結構體的基礎知識,從聲明定義到成員訪問,再到最后的結構體傳參。


一、結構體的聲明

結構體的聲明使用struct關鍵字,其基本語法如下:

struct 結構體標簽 {類型 成員1;類型 成員2;// 更多成員...
};

與數組不同,結構體的成員可以是不同類型的變量。例如,我們可以創建一個學生結構體:

struct Stu {char name[20];  // 姓名int age;        // 年齡float score;    // 成績
};

聲明結構體后,我們可以創建該類型的變量:

struct Stu s;  // 創建一個Stu類型的結構體變量s

當然我們也可以在聲明結構體的同時創建變量(此時創建的是全局變量(因為在{}外定義)):

struct Stu {char name[20];int age;float score;
} s1, s2;  // 全局變量s1和s2

而上面的在main函數內部創建的則是局部變量。

二、結構體的定義和初始化

結構體的初始化與數組類似,使用花括號{}進行初始化:

struct Stu s = {"張三", 18, 90.5};

當結構體嵌套時(即成員中包含另一個結構體),可以使用嵌套的花括號來對結構體進行初始化:

struct Date {int year;int month;int day;
};struct Student {char name[20];struct Date birthday;  // 嵌套結構體
};struct Student stu = {"李四", {2000, 5, 20}};

三、結構體成員訪問

訪問結構體成員有兩種方式:

  1. 使用.操作符直接訪問:
struct Stu s;
strcpy(s.name, "王五");
s.age = 19;
s.score = 88.5;
  1. 當有結構體指針時,使用->操作符:
struct Stu s;
struct Stu *ps = &s;
ps->age = 20;  // 等價于 (*ps).age = 20;

如在這里ps->age,表示的意思是ps先找到指向的結構體變量s,再找其成員變量age

四、結構體傳參

結構體作為函數參數傳遞時有兩種方式:

  1. 傳值調用:傳遞整個結構體對象的副本
void printStudent(struct Stu s) {printf("姓名: %s, 年齡: %d, 成績: %.1f\n", s.name, s.age, s.score);
}// 調用
printStudent(s);
  1. 傳址調用:傳遞結構體的指針
void printStudent(struct Stu *ps) {printf("姓名: %s, 年齡: %d, 成績: %.1f\n", ps->name, ps->age, ps->score);
}// 調用
printStudent(&s);

這兩種方式我們推薦使用傳址調用,原因如下:

  • 效率更高:傳值調用需要臨時拷貝整個結構體,會消耗更多內存和時間。而傳址調用只需傳遞一個指針(32位系統4字節,64位系統8字節),大大提高了傳參效率。
  • 功能更強大:通過指針可以直接修改原結構體的值,而傳值調用只能操作副本。

五、函數調用的參數壓棧(了解)

在函數調用過程中,參數會被"壓棧"(push onto the stack)。棧是一種先進后出(LIFO)的數據結構:

  • 每次函數調用都會在內存的棧區開辟一段空間
  • 參數通常從右向左依次壓棧
  • 例如Add(a, b)調用時,先壓入b,再壓入a

了解函數棧幀的創建和銷毀有助于深入理解函數調用機制,這相當于我們編程能力的"內功"。


結構體是C語言中非常重要的自定義數據類型,它允許我們將不同類型的數據組合成一個整體。通過本文,我們介紹了:

  1. 如何聲明和定義結構體
  2. 結構體的初始化和成員訪問方法
  3. 結構體傳參的兩種方式(優先使用傳址調用)
  4. 函數調用時的參數壓棧機制(了解)

掌握結構體的基礎知識是學習更高級數據結構的前提,也是編寫復雜程序的必備技能。在實際開發中,結構體經常與指針配合使用,能夠極大地提高程序的靈活性和效率。在下一章,我們將介紹一些實用的調試技巧,敬請期待!

作者其他文章鏈接:
初識C語言—人生若只如初見(完結撒花!)
[C語言初階]指針初階
[C語言初階]操作符
[C語言初階]掃雷小游戲
Gitee詳細使用教程

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

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

相關文章

LVS(Linux Virtual Server)集群技術詳解

一.集群和分布式: 集群:同一個業務系統,部署在多臺服務器上,集群中,每一臺服務器實現的功能沒有差別,數據和代碼都是一樣的 分布式:一個業務被拆成多個子業務,或者本身就是不同的業務&#…

leetcode_27 移除元素

1. 題意 給定一個數組,把不等于val的元素全部移動到數組的前面來。 不需要考慮值為val里的元素。 2. 題解 2.1 同向雙指針 我們利用雙指針,慢指針指向下一個插入的位置。而快指針不斷向前找到首個不為val的值,找到后將快指針位置值賦給慢…

Linux-Ubuntu下的git安裝與配置

一、安裝git1.打開終端,運行以下命令(需要聯網)sudo apt-get update sudo apt-get install git2.驗證安裝安裝完成之后,通過運行以下命令驗證git是否已經正確安裝:git --version二、配置git2.1.配置用戶名及郵箱地址在…

2D和3D激光slam的點云去運動畸變

在使用激光雷達設備采集點云的時候,我們都知道,激光雷達是邊運動邊采集的,每一個點云采集時的激光雷達的中心和姿態都是不一樣的,如果不加以矯正,那么這一幀數據就會出現問題,比如采集一個平面的結構的時候…

Java 熱門面試題 200 道(Markdown表格版)【簡化版】

Java 熱門面試題 200 道(Markdown表格版)【簡化版】 Java與數據庫核心面試題摘要 本文精選200道Java與數據庫高頻面試題,重點涵蓋: Java集合: HashMap原理(數組+鏈表/紅黑樹)、ConcurrentHashMap分段鎖優化、紅黑樹改進目的(解決哈希沖突性能問題) MySQL索引: 最左前…

OpenCV探索之旅:多尺度視覺與形狀的靈魂--圖像金字塔與輪廓分析

在我們學會用Canny算法勾勒處世界的輪廓之后,一個更深層次的問題擺在了面前:這些由像素組成的線條,如何才能被賦予“生命”,成為我們能夠理解和分析的“形狀”?如果一個物體在圖像中時大時小,我們又該如何穩…

Redis作緩存時存在的問題及其解決方案

Redis最常用的一個場景就是作為緩存,本文主要探討Redis作為緩存,在實踐中可能會有哪些問題?比如一致性, 穿擊, 穿透, 雪崩, 污染等。 為什么要理解Redis緩存問題 在高并發的業務場景下,數據庫大多數情況都是用戶并發訪問最薄弱的…

day17 力扣654.最大二叉樹 力扣617.合并二叉樹 力扣700.二叉搜索樹中的搜索 力扣98.驗證二叉搜索樹

最大二叉樹給定一個不重復的整數數組 nums 。 最大二叉樹 可以用下面的算法從 nums 遞歸地構建:創建一個根節點,其值為 nums 中的最大值。遞歸地在最大值 左邊 的 子數組前綴上 構建左子樹。遞歸地在最大值 右邊 的 子數組后綴上 構建右子樹。返回 nums 構建的 最大…

天地圖前端實現geoJson與wkt格式互轉

geoJson與wkt都是WebGIS開發中經常用到的格式,天地圖行政區劃邊界接口返回的是wkt格式數據,需要轉換一下。 安裝插件:terraformer/wkt npm install terraformer/wkt 兩個函數: .wktToGeoJSON(WKT) ? object.geojsonToWKT(Geo…

(1-7-3)數據庫的基本查詢

目錄 1. 數據庫的基本查詢 1.1 簡單的記錄查詢 1.2 使用列別名 2. 數據分頁查詢 (1)查詢前五行數據 (2)查詢 11 ~ 15 行數據 3. 結果集排序 3.1 單關鍵字排序 (1)升序排列 (2&#…

寶塔配置pgsql可以遠程訪問及pdo_pgsql擴展的安裝

本地navicat premium 17.0 可以遠程訪問pgsql v16.1寶塔的軟件商店里,找到pgsql管理器;在pgsql管理器里找到客戶端認證:第二步:配置修改,CtrlF 查找listen_addresses關鍵字;第三步:在navicat里配…

SQL進階:自連接的用法

目錄 一、可重排列、排列、組合 1、創建表 2、錄入數據 3、獲取可重排列的商品名稱(有序) 4、獲取排列的商品名稱(有序) 5、獲取組合的商品名稱(無序) 6、獲取3個元素的組合商品名稱(無序…

Spark集群優化配置指南

Spark集群優化配置指南 📋 概述 本文檔記錄了5節點Spark集群的性能優化配置,主要解決Thrift Server內存不足(OOM)問題和CPU資源利用率低的問題。 文檔內容 Spark架構原理: Driver與Executor的關系和工作機制Driver內存配置詳解: 三個關鍵內存參數的作用和…

Layui —— select

前言:記錄在修改bug時遇到的一些奇怪問題。遇到的奇怪問題1:項目中引入了 layui,而且也使用了 layui.use 按需導入了需要的組件,但是在頁面每次剛初始化的時候去使用layui,控制臺都會報 組件未定義的問題(正…

代碼隨想錄day32dp1

文章目錄509. 斐波那契數70. 爬樓梯746. 使用最小花費爬樓梯確定dp數組(dp table)以及下標的含義 確定遞推公式 dp數組如何初始化 確定遍歷順序 舉例推導dp數組509. 斐波那契數 題目鏈接 文章講解 class Solution { public:int fib(int n) {// 1. 確定…

RedisJSON 技術揭秘`JSON.ARRTRIM`用窗口裁剪,讓數組保持“剛剛好”

1、指令速查 JSON.ARRTRIM <key> <path> <start> <stop>key&#xff1a;Redis 鍵名path&#xff1a;JSONPath&#xff0c;默認 $ 根&#xff1b;可用 .[*]/.. 多路徑匹配start / stop&#xff1a;要保留的 [start, stop] 閉區間索引 支持負值&#xff…

fpga調試經驗

fpga調試經驗 調測場景&#xff1a; 外接adc傳感器芯片&#xff0c;采集壓力&#xff0c;溫度等模擬量&#xff0c;fpga通過spi/i2c接口與adc傳感器芯片通信 問題1&#xff1a;adc芯片在穩定環境中&#xff0c;輸出數字量不穩定。 結論&#xff1a;adc輸入電壓由fpga板供應&…

cefSharp.WinForms.NETCore 138.xx (cef138/Chromium 138.0.7204.97) 升級測試體驗

一、版本說明及變化 該版本支持cef138.0.x系列,cefsharp138.0.170 無重大更新;該版本暫不支持h264,請關注后續 關注欄目,關注我,學習cefsharp少走彎路 不迷路! CefSharp 設置緩存的注意事項參考 說明:欄目是訂閱文章,無附件,如需要單獨獲取(看底部介紹說明) 該版本1…

chatgpt是怎么誕生的,詳解GPT1到GPT4的演化之路及相關背景知識

人工智能革命正在發生&#xff0c;我們是何其幸運的一代&#xff0c;能親眼見證人類/機器智能的大爆發。 僅僅作為這場革命的看客顯然是有些遺憾的&#xff0c;如何進一步了解它&#xff1f; 本文將討論chatgpt的誕生過程&#xff0c;串聯起OpenAI發表的一系列重要論文&#…

[筆記] 動態 SQL 查詢技術解析:構建靈活高效的企業級數據訪問層

文章目錄一. 應用場景二. 使用示例示例1示例2示例3三. 實現1. 動態表查詢構建器&#xff0c;模仿MyBatis-Plus2. mapper3. mapper.xml功能概述參數說明四. 動態 SQL 的優化與風險防控在企業級應用開發中&#xff0c;數據查詢場景往往呈現出復雜多變的特點 —— 從簡單的單表篩選…