輕松拿捏C語言——自定義類型之【結構體】

?

🥰歡迎關注?輕松拿捏C語言系列,來和 小哇 一起進步!?

🎉創作不易,請多多支持🎉

🌈感謝大家的閱讀、點贊、收藏和關注💕

🌹如有問題,歡迎指正


1. 結構體類型的聲明

結構體是一些值的集合

這些值叫做 成員分量

結構的每個成員變量可以是不同的類型

例如描述一個學生:

struct Stu
{char name[20];//名字int age;//年齡char sex[5];//性別char id[20];//學號
}; //分號不能丟

這是結構體的聲明

struct 是結構體關鍵字,struct Stu 是這個結構體類型名?

2. 結構體變量的創建和初始化

#include <stdio.h>
struct Stu
{char name[20];//名字int age;//年齡char sex[5];//性別char id[20];//學號
};
int main()
{//按照結構體成員的順序初始化struct Stu s = { "張三", 20, "男", "20230818001" };printf("name: %s\n", s.name);printf("age : %d\n", s.age);printf("sex : %s\n", s.sex);printf("id : %s\n", s.id);//按照指定的順序初始化struct Stu s2 = { .age = 18, .name = "lisi", .id = "20230818002", .sex = 
"?" };printf("name: %s\n", s2.name);printf("age : %d\n", s2.age);printf("sex : %s\n", s2.sex);printf("id : %s\n", s2.id);return 0;
}

在進行結構體聲明時,也可以進行不完全聲明:

//匿名結構體類型
struct
{int a;char b;float c;
}x;struct
{int a;char b;float c;
}a[20], *p;

上?的兩個結構在聲明的時候省略掉了結構體標簽

上?的兩個聲明是完全不同的兩個類型。

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

在結構中包含?個類型為該結構本?的成員是不可以的

例如 :

struct Node
{int data;struct Node next;
};

這是錯誤的用法。

因為?個結構體中再包含?個同類型的結構體變量,這樣結構體變量的大小就會?窮的?,是不合理的?

正確自引用方式:

struct NOde
{int data;struct Node* next;//定義一個結構體類型指針
};

在結構體自引用使用的過程中,夾雜了 typedef 對匿名結構體類型重命名,也容易引入問題,比如:

typedef struct
{int data;Node* next;
}Node;

?這是錯誤用法,因為Node是對前面的匿名結構體類型的重命名產?的,但是在匿名結構體內部提前使用Node類型來創建成員變量,這是不行的

所以定義結構體不要使用匿名結構體了

typedef struct Node
{int data;struct Node* next;
}Node;

3. 結構體內存對齊

結構體成員在內存中存在對齊現象

內存對齊的原因:

? ? ? ? 1、平臺原因(移植原因):

不是所有的硬件平臺都能訪問任意地址上的任意數據的;某些硬件平臺只能在某些地址處取某些特定類型的數據,否則拋出硬件異常

? ? ? ? 2、性能原因:

數據結構(尤其是棧)應該盡可能地在自然邊界上對齊。原因在于,為了訪問未對齊的內存,處理器需要作兩次內存訪問;而對齊的內存訪問僅需要?次訪問。

所以結構體的內存對齊是拿空間來換取時間的做法,提高程序運行效率,節省空間

對齊規則:

????????1. 結構體的第?個成員對齊到和結構體變量起始位置偏移量為0的地址處

????????2. 其他成員變量的首地址與結構體首地址的偏移量要為 該成員對齊數的整數倍

? ? ? ? ? ? ? ? 對齊數 = 編譯器默認的?個對齊數 與 該成員變量大小的較小值

????????????????VS 中默認的值為 8 ,?Linux中 gcc 沒有默認對齊數,對齊數就是成員自身的大小

? ? ? ? 3、結構體總大小為最大對齊數(結構體中每個成員變量都有?個對齊數,所有對齊數中最大的)的 整數倍

? ? ? ? 4、?如果嵌套了結構體的情況,嵌套的結構體成員對齊到自己的成員中最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含嵌套結構體中成員的對齊數)的整數倍。

如果我們把讓占用空間小的成員盡量集中在?起,更節省空間,比如:

struct S1
{char c1;int i;char c2;
};
struct S2
{char c1;char c2;int i;
};

S1中結構體大小為 12字節,S2結構體大小為8,因為S2中兩個char類型的變量放在了一起(放在int類型的前后都一樣,都是8).

我們可以使用#pragma 這個預處理指令,可以改變編譯器的默認對齊數

#include <stdio.h>
#pragma pack(1)//設置默認對?數為1
struct S
{char c1;int i;char c2;
};
int main()
{printf("%d\n", sizeof(struct S));return 0;
}

這里結果為6,因為默認對齊系數改為了1,所以是1+4+1?

可以用#pragma pack()//取消設置的對齊數,還原為默認

4. 結構體傳參

結構體傳參的時候,要傳結構體的地址

struct S
{int data[1000];int num;
};
struct S s = {{1,2,3,4}, 1000};
//結構體傳參
void print1(struct S s)
{printf("%d\n", s.num);
}
//結構體地址傳參
void print2(struct S* ps)
{printf("%d\n", ps->num);
}
int main()
{print1(s); //傳結構體print2(&s); //傳地址return 0;
}

print1和print2這兩個函數中,print2函數更好,

因為函數傳參的時候,參數是需要壓棧,會有時間和空間上的系統開銷。

如果傳遞?個結構體對象的時候,結構體過大,參數壓棧的的系統開銷比較大,所以會導致性能的下降。?

5. 結構體實現位段

位段的聲明和結構是類似的,有兩個不同:

1. 位段的成員必須是 int、unsigned int 或signed int 或者是 char 等類型,在C99中位段成員的類型也可以選擇其他類型。(一般就是int家族)

2. 位段的成員名后邊有?個冒號和?個數字。

例如:

struct A
{int _a:2;int _b:5;int _c:10;int _d:30;
};

?這里位段A所占內存大小為8字節

位段的空間上是按照需要以4個字節( int )或者1個字節( char )的方式來開辟的

位段涉及很多不確定因素,位段是不跨平臺的,注重可移植的程序應該避免使用位段

跟結構體相比,位段可以達到同樣的效果,并且可以很好的節省空間,但是有跨平臺的問題存在:

????????1. int 位段被當成有符號數還是無符號數是不確定的。

???????? 2. 位段中最大位的數目不能確定。(16位機器最大16,32位機器最大32,寫成27,在16位機器會出問題。

????????3. 位段中的成員在內存中從左向右分配,還是從右向左分配,標準尚未定義。

???????? 4. 當?個結構包含兩個位段,第?個位段成員比較大,無法容納于第?個位段剩余的位時,是舍棄剩余的位還是利用,這是不確定的。

位段的幾個成員共有同?個字節,這樣有些成員的起始位置并不是某個字節的起始位置,那么這些位 置處是沒有地址的。

內存中每個字節分配?個地址,?個字節內部的bit位是沒有地址的。

所以不能對位段的成員使用&操作符,這樣就不能使用scanf直接給位段的成員輸入值,只能是先輸入放在?個變量中,然后賦值給位段的成員。

例如:

struct A
{int _a : 2;int _b : 5;int _c : 10;int _d : 30;
};
int main()
{struct A sa = {0};scanf("%d", &sa._b);//這是錯誤的//正確的?范int b = 0;scanf("%d", &b);sa._b = b;return 0;
}

?🎉🎉🎉本文內容結束啦,希望各位大佬多多指教!

🌹🌹感謝大家三連支持

💕敬請期待下篇~💥

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

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

相關文章

echarts-象形柱圖

象形柱圖 一般的柱圖都是純色柱圖&#xff0c;使用象形柱圖可以給柱圖定義自己的樣式。 樣式的調節與柱圖一樣&#xff0c;核心在于symbol調節柱圖的組成。 let options {tooltip: {},xAxis: {type: "category",data: ["d1", "d2", "d3&qu…

具有固定寬度的盒子:\makebox, \parbox

makebox \makebox 是 LaTeX 中的一個命令&#xff0c;用于創建一個具有固定寬度的盒子&#xff0c;并在該盒子內放置內容。這個命令可以用于控制文本或對象的位置和對齊。 語法如下&#xff1a; \makebox[<width>][<alignment>]{<content>}其中&#xff1…

存儲+調優:存儲-memcached

存儲調優&#xff1a;存儲-memcached 什么是memcached? 高性能的分布式內存緩存服務器。通過緩存數據庫的查詢結果&#xff0c;減少數據庫訪問次數&#xff0c;以提高動態Web應用的速度、提高可擴展性。 在memcached中存什么&#xff1f; 盡快被保存 訪問頻率高 1.數據保…

【CSharp】int類型與IntPtr類型之間的轉換

【CSharp】int類型與IntPtr類型之間的轉換 1.背景2.int轉IntPtr接口3.IntPtr轉int接口4.相互轉化示例1.背景 .NET提供了一個結構體System.IntPtr專門用來代表句柄或指針。 IntPtr 結構,表示一個帶符號整數,其中位寬度與指針相同。 注解 類型 IntPtr 設計為一個整數,其大小…

unity回到低版本報錯解決

用高版本2022打開過后的再回到2020就報了一個錯。 報錯如下&#xff1a; Library\PackageCache\com.unity.ai.navigation1.1.5\Runtime\NavMeshSurface.cs 看了一下是Library&#xff0c;然后我刪除了整個Library文件夾&#xff0c;重啟啟動生成Library&#xff0c;然后還是…

IT人的拖延——渴望成功與害怕成功的矛盾

很多人都以為&#xff0c;害怕失敗是拖延的主要誘因&#xff0c;但其實“害怕成功”也是拖延的主要誘因之一。要說這個原因&#xff0c;我們不得不提起Bible中的一個人“約拿”&#xff0c;讓我們先來看看他的故事帶給我們什么啟示。 約拿情結簡介 約拿是Bible中的一名先知&a…

二十九、openlayers官網示例DeclutterGroup解析——避免矢量圖層的文字重疊

官網demo地址&#xff1a; Declutter Group 這篇說的是如何設置矢量圖層上多數據點文字不重疊。 主要是屬性declutter &#xff0c;用于處理矢量圖層上重疊的標注和符號&#xff0c;為true時啟用去重疊功能。所有矢量特征的標注和符號都會被處理以避免重疊。false則與之相反。…

Nuxt - middleware 路由中間件

官方文檔&#xff1a;https://nuxt.com.cn/docs/guide/directory-structure/middleware 目錄 1 中間件類別2 中間件執行順序3 內聯路由中間件4 命名路由中間件5 全局路由中間件 1 中間件類別 內聯路由中間件&#xff0c;直接在頁面內定義。命名路由中間件&#xff0c;放置在 …

es安裝錯誤Exception in thread “main“ java.nio.file.NoSuchFileException解決方案

docker 啟動es出現一下錯誤的解決方案 Exception in thread “main” java.nio.file.NoSuchFileException: /usr/share/elasticsearch/config/jvm.options Exception in thread "main" java.nio.file.NoSuchFileException: /usr/share/elasticsearch/config/jvm.op…

香橙派OrangePi AIpro,助力國產AIoT邁向新的臺階!

前言&#xff1a;很高興受邀CSDN與OrangePi官方組織的測評活動&#xff0c;本次測評是一塊基于AI邊緣計算的香橙派開發板OrangePi AIpro。這是 香橙派 聯合 華為昇騰 合作精心打造的新一代邊緣AI計算產品&#xff0c;于2023年12月初發布&#xff0c;提供 8/20TOPS澎湃算力[1]&a…

Java | Leetcode Java題解之第102題二叉樹的層序遍歷

題目&#xff1a; 題解&#xff1a; class Solution {public List<List<Integer>> levelOrder(TreeNode root) {Queue<TreeNode> queue new LinkedList<>();List<List<Integer>> res new ArrayList<>();if (root ! null) queue.a…

Bean的一些屬性信息總結

我們知道&#xff0c;在Spring中&#xff0c;一個Bean可以理解為一個對象&#xff0c;但是二者之間肯定是有區別的&#xff0c;比如一個Bean可以實例化成很多個對象、Bean中可以帶有某些描述信息。 學習Bean&#xff0c;能更好地使用Bean。 1、Spring兩個核心概念的由來【可忽…

Git和plink

安裝git的話首先進入到git官網進行下載Git - Downloading Package (git-scm.com) &#xff0c;點擊便會自動進行下載。 安裝plink時也是根據自己電腦的版本號選擇進行安裝&#xff0c;我的是windows的64位&#xff0c;由此選擇以上版本進行安裝&#xff0c;這一個下載完成之后不…

python lxml安裝失敗怎么解決

通過pip install lxml 安裝lxml多次失敗&#xff0c;失敗原因總結如下&#xff1a; 1、pip版本未更新 解決方法&#xff1a;通過pip安裝時&#xff0c;需保證pip的版本沒有問題。 更新方法&#xff1a;在系統框輸入&#xff1a;python -m pip install --upgrade pip 2、下載…

oracle 還原被覆蓋的視圖

1.現在的視圖 select to_lob(text) from SYS.DBA_views where view_nameXXX; 2.查舊數據 --as of timestamp to_date(2024-05-28 10:30:00,yyyy-mm-dd hh24:mi:ss) select to_lob(text) from SYS.DBA_views as of timestamp to_date(2024-05-28 10:30:00,yyyy-mm-dd hh24:mi:s…

好消息!DolphinScheduler官網集成LLM模型問答AI kapa.ai

不少小伙伴可能發現了&#xff0c;Apache DolphinScheduler官網最近默默上線了kapa.ai作為LLM的問答AI。 集成kapa.ai之后&#xff0c;社區用戶可以點擊Apache DolphinScheduler官網首頁右下角的「Ask AI」模塊&#xff0c;在接下來彈出的問答框輸入自己的問題&#xff0c;即可…

python uiautomator2 常用操作

uiautomator2 安裝 python uiautomator2 安裝及使用-CSDN博客 一&#xff0c; 通過包名可以打開app d.app_start(com.gacne.www) 打開app運行后執行代碼&#xff0c;查看app具體信息獲取包名 d.info二&#xff0c;執行等待點擊 # 160秒內等待xpath定位的出現執行點擊 d.xpat…

mysql中單表查詢的成本

大家好。我們知道MySQL在執行一個查詢時&#xff0c;經常會有多個執行方案&#xff0c;然后從中選取成本最低或者說代價最低的方案去真正的執行查詢。今天我們來聊一聊單表查詢的成本。 那么到底什么是成本呢&#xff1f;這里我們說的成本或者代價是由兩方面組成的&#xff1a…

【踩坑】編譯opencv將python (for build) python2.7改為python3

轉載請注明出處&#xff1a;小鋒學長生活大爆炸[xfxuezhagn.cn] 如果本文幫助到了你&#xff0c;歡迎[點贊、收藏、關注]哦~ 出現問題 默認是2.7 解決方案 cmake時候添加&#xff1a; -D PYTHON_DEFAULT_EXECUTABLE$(which python3)

詳盡的Ubuntu 24.04 LTS安裝指南

Ubuntu安裝過程涉及多個步驟&#xff0c;下面是一個詳盡的Ubuntu 24.04 LTS安裝指南 ### 一、準備工作 **1. 系統要求** * **CPU**&#xff1a;至少2GHz雙核處理器。 * **內存**&#xff1a;推薦4GB或以上。 * **硬盤**&#xff1a;建議至少預留25GB可用空間。 * **U盤**&am…