<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
struct { char name[20]; int age; }s1;
匿名結構體物件s1過了這一行即銷燬。
struct Node { int data; struct Node next;//錯誤的,嚴禁自己參照自己 }; struct Node { int data; struct Node* next;//正確的參照方式 };
typedef struct { int data; Node* next;//錯誤的,不要再重新命名中使用重新命名 }Node; typedef struct Node { int data; struct Node* next;//正確的 }Node;
博主在學資料結構的時候踩過這個坑,在結構體重新命名的時候成員變數的型別就使用了重新命名,導致整個程式不認識這個成員變數的型別(但是vs在typedef這裡不報錯,而是在每個使用這個型別的地方報錯!!!)。後來把這個成員變數的型別修改為重新命名之前的型別,整個程式就可以執行了。(如上圖的正確寫法)
第一個成員在與結構體變數偏移量為0的地址處。
後續成員變數要放到各自的對齊數的倍數上。對齊數 = 編譯器預設對齊數與該成員型別大小的較小值。(vs中預設對齊數是8,gcc沒有預設對齊數)
結構體最終大小為最大對齊數的整數倍。
如果巢狀了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍。
struct S1 { char c1; int i; char c2; }; int main() { printf("%dn", sizeof(struct S1)); return 0; }
char c1在結構體變數的零偏移量處分配記憶體
int i的對齊數為4,所以跳過3個位元組,在4的整數倍地址處分配記憶體
char c2的對齊數為1,使用下一個位元組空間即可
目前已使用9位元組
由於該結構體中所有成員變數中最大的成員型別大小為4位元組,所以最大記憶體對齊數為4位元組,結構體總大小為最大對齊數的整數倍。所以該結構體記憶體為12位元組。
可以使用宏offsetof來觀察結構體成員在記憶體中的偏移量:
struct S3//16 { double d; char c; int i; }; struct S4//32 { char c1; struct S3 s3; double d; };
char c1在結構體變數的零偏移量處分配記憶體
struct S3 s3按照其最大記憶體對齊數(此處為8)進行對齊
double d按照其最大記憶體對齊數(8)進行對齊
S4的最大記憶體對齊數為8,所以結構體的最終大小為32
通過上述例子可以發現,結構體成員之間有很大的空間浪費,哪怕是擁有相同結構體成員的兩個結構體型別,其在記憶體中所佔據的空間也不相同,所以為了空間的節省,在不影響資料結構的情況下,有目的的把位元組佔用小的成員變數放在一起,達到節省空間的目的。
1. 平臺原因(移植原因)
不是所有的硬體平臺都能存取任意地址上的任意資料的;某些硬體平臺只能在某些地址處取某些特定型別的資料,否則丟擲硬體異常。
2. 效能原因(空間換時間)
資料結構(尤其是棧)應該儘可能地在自然邊界上對齊。 原因在於,為了存取未對齊的記憶體,處理器需要作兩次記憶體存取;而對齊的記憶體存取僅需要一次存取。
#pragma pack(2)//把預設對齊數改成2 struct S { char c1; int i; short c2; }; #pragma pack()//恢復預設對齊數為8 int main() { printf("%dn", sizeof(struct S)); return 0; } #pragma pack(num)修改預設對齊數,該結構體的記憶體大小由12位元組降低為8位元組。
預設對齊數儘量為2的次方。
結構體傳參要傳地址。
傳址呼叫優於傳值呼叫的原因是地址佔4/8個位元組。
但是傳值呼叫引數需要壓棧,當結構體過大時,引數壓棧的系統開銷較大。
位元欄是在結構體中實現的。
位元欄的成員可以是 int、unsigned int、signed int或者是char型別
位元欄的空間增長方式為每次增長4個位元組(int)或1個位元組(char)
位元欄涉及很多不確定因素,位元欄是不跨平臺的,注重可移植的程式應該避免使用位元欄。
1.1位元欄中char型別的儲存方式(vs中捨棄剩餘空間)
struct S//佔用3個位元組 { char _a : 3; char _b : 4; char _c : 5; char _d : 4; }; int main() { printf("%dn", sizeof(struct S)); struct S s= { 0 }; s._a = 10;//1010,截斷為010 s._b = 12;//1100 s._c = 3;//0011 s._d = 4;//0100 return 0; }
通過呼叫記憶體發現,&s中儲存的16進位制數位為62 03 04,那麼可以發現s在記憶體中的儲存方式如下圖:
在vs環境中,char成員變數在單個位元組中是倒著儲存的(有截斷先發生截斷),當該位元組中剩餘的位元位不足以存放下一個完整的成員變數時,會將剩餘的位元位捨棄。
1.2位元欄中int型別的儲存方式(vs中利用剩餘空間)
struct A//佔4個位元組 { int a : 2; int b : 3; int c : 4; }; int main() { struct A s = { 0 }; s.a = 12;//1100,截斷為00 s.b = 13;//1101,截斷為101 s.c = 14;//1110 return 0; }
通過呼叫記憶體發現,&s中儲存的16進位制數位為d4 01 00 00,那麼可以發現s在記憶體中的儲存方式如下圖:
在vs環境中,int成員變數在單個位元組中是倒著儲存的(有截斷先發生截斷),當該位元組中剩餘的位元位不足以存放下一個完整的成員變數時,會將繼續儲存,存不下的二進位制位將存放至下一個位元組的右側。
注意:位元欄冒號後面的數位只能小於等於型別大小(例如char a:9是錯誤的)
1.int 位元欄被當成有符號數還是無符號數是不確定的。
2. 位元欄中最大位的數目不能確定。(16位元機器最大16,32位元機器最大32,寫成27,在16位元機器會出問題。
3. 位元欄中的成員在記憶體中從左向右分配,還是從右向左分配標準尚未定義。
4. 當一個結構包含兩個位元欄,第二個位元欄成員比較大,無法容納於第一個位元欄剩餘的位時,是捨棄剩餘的位還是利用,這是不確定的。
enum color { RED,//列舉常數 BLUE, YELLOW };
不賦值那麼預設從0開始,後續列舉元的值遞增1
enum color { RED=1, BLUE, YELLOW };
只需要對第一個成員進行賦值,後續列舉元的值遞增1
在寫列舉元的時候建議全大寫,博主在寫通訊錄列舉了exit,使用時vs提示該命名和exit函數衝突。
增加程式碼的可讀性和可維護性
列舉使用時有型別檢查,#define定義的識別符號沒有
防止了命名汙染(封裝)
便於偵錯(#define定義宏在預處理時是直接替換)
使用方便,一次可以定義多個常數
聯合也是一種特殊的自定義型別 這種型別定義的變數也包含一系列的成員,特徵是這些成員共用同一塊空間(所以聯合也叫共用體)。
#include <stdio.h> union un { char arr[5]; int a; }u; int main() { printf("%d", sizeof(u));//8 return 0; }
聯合體的大小至少是最大成員的大小。
最大記憶體對齊數的整數倍要大於等於最大成員的大小。
(這裡最大成員是arr,佔5個位元組,最大記憶體對齊數是4,所以需要為祖國聯合體開闢8個位元組空間)
#include <stdio.h> union un { int m; char n; }u; int check_sys() { u.m = 1; return u.n; } int main() { int a = check_sys(); if (a == 1) printf("小端儲存n"); else printf("大端儲存n"); return 0; }
以上就是詳解C語言結構體,列舉,聯合體的使用的詳細內容,更多關於C語言 結構體 列舉 聯合體的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45