摘要:如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對齊到自己的最大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對齊數(shù)含嵌套結(jié)構(gòu)體的對齊數(shù)的整數(shù)倍。
?
?
?
?
?
?
結(jié)構(gòu)體的基礎(chǔ)知識: 結(jié)構(gòu)是一些值的集合,這些值稱為成員變量。結(jié)構(gòu)的每個成員可以是不同類型的變量
?
程序一:
#include //聲明一個結(jié)構(gòu)體類型//聲明一個學(xué)生類型,是 想通過 學(xué)生類型 來創(chuàng)建 學(xué)生變量(對象)// 描述學(xué)生 : 屬性 + 名字 + 性別 + 年齡 + 電話 struct student// struct 結(jié)構(gòu)體 關(guān)鍵字 student 結(jié)構(gòu)體 標(biāo)簽{ char name[10]; char sex[20]; int age; char telephone[12];// 這四個變量 就是結(jié)構(gòu)體的成員變量}s4,s5,s6; // 創(chuàng)建 結(jié)構(gòu)體 全局變量// 以上所有 就是一個 結(jié)構(gòu)體類型struct student s3; // 創(chuàng)建 結(jié)構(gòu)體 全局變量int main(){ //創(chuàng)建 結(jié)構(gòu)體變量 的方式 struct student s1; struct student s2; // 因為 這兩個變量放在 main 函數(shù)里,所以是 局部變量 return 0;}
?
程序一:
#include struct // 缺少一個標(biāo)簽(名字) 這種結(jié)構(gòu)體類型 稱為 匿名結(jié)構(gòu)體類型 { // 那么問題來了,沒有名字 該 如何 創(chuàng)建 結(jié)構(gòu)體 變量 ? char name[10]; char sex[20]; int age; char telephone[12];}x;// 只有一種方式在結(jié)構(gòu)體末尾分號(;)前面 創(chuàng)建 結(jié)構(gòu)體 全局變量struct // 缺少一個標(biāo)簽(名字) 這種結(jié)構(gòu)體類型 稱為 匿名結(jié)構(gòu)體類型 { char name[10]; char sex[20]; int age; char telephone[12];}* px;// 在 匿名結(jié)構(gòu)體 的 全部變量 px 前面加上 * ,該 匿名結(jié)構(gòu)體類型 變成了 匿名結(jié)構(gòu)體指針類型// 即 * px 是一個結(jié)構(gòu)體指針int main(){ px = &x; // 經(jīng)過 編譯器 編譯, 程序報警,該表達(dá)式 是 不合法的 //因為 編譯器, 會把 它們 當(dāng)做 2 種 不同類型 來處理 // 所以 兩種 不同類型 的數(shù)據(jù),是無法進(jìn)行賦值 return 0;}
?
程序一:
#include struct node{ int data; struct node* next;// 如果 沒有 * 號,也就是數(shù) next 是本身的結(jié)構(gòu)體變量,會導(dǎo)致這個結(jié)構(gòu)體所占內(nèi)存無限大。 // 這里存地址, 存的是下一個數(shù)據(jù)的地址: //結(jié)構(gòu)體自引用 就是 結(jié)構(gòu)體 用指針 找到 與自身同類型的 結(jié)構(gòu)體變量 // 而不是說 結(jié)構(gòu)體自己 包含 結(jié)構(gòu)體自己 的 變量 : struct node next (error)};int main(){ return 0;}
?
程序二:
#include typedef struct node // 這里的 node 是不能省略的, 要不然 下面 沒有這 struct node* next 類型,只能寫成 node* next{ // 但是 node 是 [把 省略了 node 從而 變成 匿名結(jié)構(gòu)體 的 重命名]。 是后有的, // 也就是說 node 還沒有生成, 就在結(jié)構(gòu)體 調(diào)用它, // 這種寫法 是錯誤的 int data; struct node* next;}node; // node : typedef 把 結(jié)構(gòu)體 struct node 簡化成 nodeint main(){ node n; return 0;}
?
?
程序一:
#include struct s{ char c; int a; double d; char arr[20];};int main(){ struct s s = { "c", 100, 3.14, "hellworld" }; printf("%c %d %lf %s/n", s.c, s.a, s.d, s.arr); return 0;}
?
程序二:
#include struct t{ double weight; short age;};struct s{ char c; int a; double d; char arr[20]; struct t st;};int main(){ struct s s = { "c", 100, 3.14, "hellworld", {55.6,30} }; printf("%c %d %lf %s %lf %d/n", s.c, s.a, s.d, s.arr, s.st.weight, s.st.age); return 0;}
?
對齊數(shù) = 編譯器默認(rèn) 的 一個對齊數(shù) 與 成員大小的 較小值
vs 中 默認(rèn)的值為 8; gcc 沒有默認(rèn)對齊數(shù)(成員的大小,就是對齊數(shù))
比如 結(jié)構(gòu)體里 有一個 成員(變量) 為 整形 int 類型 為 4byte
// 而 vs 中 默認(rèn)值為 8, 4 < 8, 取 4,
// 那么 該成員的 對齊數(shù) 為 4
struct s{ char c1;// 第一個成員 在與 結(jié)構(gòu)體變量 偏移量為 0 的 地址處 (內(nèi)存所占 1 字節(jié)) int a; // a 對齊數(shù) 是 4 ,因為 其他成員 變量 要對齊 對齊數(shù)(4) 的 整數(shù)倍 的 地址處(地址4) // 從 c1(0 地址) 后面開始(從地址 4 開始) 地址 4 處 存放 a,就是說 c1 與 a 之間 隔了 3 個 地址(1,2,3) -> 3 字節(jié) // 此時 a 末尾地址 為 地址8 (因為 a 的存儲 需要 4 byte 空間) char c2;// c2 對齊數(shù) 1 ; 其他成員 變量 要對齊 對齊數(shù)(1)的 整數(shù)倍(倍數(shù)為 1) 的 地址處 也就是緊跟 a 后面的 地址8,(char 1 byte)存完之后,末尾地址指向 9; // 無論是地址幾,都是 對齊數(shù) 1 的倍數(shù) // 至此,1+3+4+1 為 9 字節(jié) // 結(jié)構(gòu)體 總大小 為9 字節(jié),但此時地址,不是 成員中 最大 對齊數(shù)(4) 的整數(shù)倍, // 12 滿足 // 所以 結(jié)構(gòu)體的大小 最后 為 12 byte};struct s2{ char c1;// 第一個成員 在與 結(jié)構(gòu)體變量 偏移量為 0 的 地址處 (1字節(jié)) char c2;// 對齊數(shù)為 1 -> 其他成員 變量 要對齊 對齊數(shù)的 整數(shù)倍( 倍數(shù)為 1 ) 的 地址處(地址1) ,c2 的存儲地址 緊跟在 c1 的后面(2 字節(jié)) int a;// 對齊數(shù) 4 -> 其他成員 變量 要對齊 對齊數(shù)的 整數(shù)倍( 倍數(shù)為 4 ) 的 地址處(地址4),(c1 是 0 地址,c2 是1 地址,浪費 2,3地址) // 即 來到 地址4, 也就是 a 的地址,也就是說 a 與 c2 隔了 2 個地址(浪費了2字節(jié)空間),a 的 存儲 也要 占 4 字節(jié) // 1 + 1 + 2 + 4 == 8 字節(jié) // 成員中 最大對齊數(shù)(4) 的整數(shù)倍 // 因為 8 == 2*4 > 6 滿足條件 // 所以最后 結(jié)構(gòu)體總大小 為 8};int main(){ struct s s = { 0 }; struct s2 s2 = { 0 }; printf("%d/n", sizeof(s));// 12 printf("%d/n", sizeof(s2));// 8 return 0;}
12 byte ,滿足成員中 最大 對齊數(shù)(4) 的整數(shù)倍, 即 結(jié)構(gòu)體大小 為 12 byte
?
?
?
?
程序二:
#include struct s3{ double d;// 第一個成員 在 與 結(jié)構(gòu)體 偏移量為 0 的地址處(double 8字節(jié),此時地址 指向地址7) char c;// 對齊數(shù) 1 地址8(9字節(jié)) int i;// 對齊數(shù) 4 c 后面的 是 地址9,不滿足倍數(shù)條件,地址 12 滿足(浪費 9,10,11地址,即 3字節(jié)空間),即 i 的地址 是 地址12 // i 占 4 字節(jié), // 8 + 1 + 3 +4 == 16 // 16 滿足成員中 最大對齊數(shù)(8)的整數(shù)倍};int main(){ printf("%d/n", sizeof(struct s3));// 16}
?
?
程序二:
#include struct s3{ double d;// 對齊數(shù) 8 地址 7 char c;// 對齊數(shù) 1 地址 8 int i;// 對齊數(shù) 4 地址 12 i 存儲 需要 4byte ,地址 16 // 結(jié)構(gòu)體大小 16 byte 滿足 最大 對齊數(shù)(8) 的整數(shù)倍 // 故結(jié)構(gòu)體 真正大小 為 16字節(jié)};struct s4{ char c1; // 地址0, 對齊數(shù) 1 // 嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體 對齊 到自己的 最大 對齊數(shù)(8) 的整數(shù)倍處 struct s3 s3; // 對齊地址 8 然后 結(jié)構(gòu)體 s3 內(nèi)存大小 為 16 byte // 存完16byte之后,地址 24 double d; // 對齊數(shù) 8 ,地址24 滿足 對齊數(shù) 整數(shù)倍 地址 // 地址 24 到 地址 32 // 32 滿足 最大 對齊數(shù)(8)的整數(shù)倍 // 結(jié)構(gòu)體 變量 s4 內(nèi)存大小 32 字節(jié) };int main(){ printf("%d/n", sizeof(struct s4));// 32}
?
?
?
?
?
?
struct s{ char c1;// 第一個成員 在與 結(jié)構(gòu)體變量 偏移量為 0 的 地址處 (內(nèi)存所占 1 字節(jié)) int a; // a 對齊數(shù) 是 4 ,因為 其他成員 變量 要對齊 對齊數(shù)(4) 的 整數(shù)倍 的 地址處(地址4) // 從 c1(0 地址) 后面開始(從地址 4 開始) 地址 4 處 存放 a,就是說 c1 與 a 之間 隔了 3 個 地址(1,2,3) -> 3 字節(jié) // 此時 a 末尾地址 為 地址8 (因為 a 的存儲 需要 4 byte 空間) char c2;// c2 對齊數(shù) 1 ; 其他成員 變量 要對齊 對齊數(shù)(1)的 整數(shù)倍(倍數(shù)為 1) 的 地址處 也就是緊跟 a 后面的 地址8,(char 1 byte)存完之后,末尾地址指向 9; // 無論是地址幾,都是 對齊數(shù) 1 的倍數(shù) // 至此,1+3+4+1 為 9 字節(jié) // 結(jié)構(gòu)體 總大小 為9 字節(jié),但此時地址,不是 成員中 最大 對齊數(shù)(4) 的整數(shù)倍, // 12 滿足 // 所以 結(jié)構(gòu)體的大小 最后 為 12 byte};struct s2{ char c1;// 第一個成員 在與 結(jié)構(gòu)體變量 偏移量為 0 的 地址處 (1字節(jié)) char c2;// 對齊數(shù)為 1 -> 其他成員 變量 要對齊 對齊數(shù)的 整數(shù)倍( 倍數(shù)為 1 ) 的 地址處(地址1) ,c2 的存儲地址 緊跟在 c1 的后面(2 字節(jié)) int a;// 對齊數(shù) 4 -> 其他成員 變量 要對齊 對齊數(shù)的 整數(shù)倍( 倍數(shù)為 4 ) 的 地址處(地址4),(c1 是 0 地址,c2 是1 地址,浪費 2,3地址) // 即 來到 地址4, 也就是 a 的地址,也就是說 a 與 c2 隔了 2 個地址(浪費了2字節(jié)空間),a 的 存儲 也要 占 4 字節(jié) // 1 + 1 + 2 + 4 == 8 字節(jié) // 成員中 最大對齊數(shù)(4) 的整數(shù)倍 // 因為 8 == 2*4 > 6 滿足條件 // 所以最后 結(jié)構(gòu)體總大小 為 8};
?
?
程序一:
#include #pragma pack(4) // 設(shè)計 默認(rèn)對齊數(shù) 為 4struct s{ char c1;// 1 // 浪費 3 個字節(jié)(原本要浪費 7 個 字節(jié),現(xiàn)在只需 3 個字節(jié)) double d; // 8 byte 對齊 為 對齊數(shù) 4,【4與8 選擇較小的】 的整數(shù)倍 的地址 // 存儲 d 需要 8 個字節(jié) 加上前面浪費 3 個 和 c1 1個 字節(jié) // 1+3+8 == 12 字節(jié) // 這樣寫法,幫我們 避免 了 4 字節(jié) 的 空間浪費};#pragma pack() // 取消設(shè)置的 默認(rèn) 對齊數(shù)
?
程序二:
那 我們把 默認(rèn)對齊數(shù) 設(shè)置為 1 呢?#include #pragma pack(1) // 設(shè)計 默認(rèn)對齊數(shù) 為 1struct s{ char c1;// 1 // 一個字節(jié)的都不會浪費 double d; // 8 byte 對齊 為(對齊數(shù) 1,【1與8 選擇較小的】) 的整數(shù)倍 的地址 // 存儲 d 需要 8 個字節(jié) // 1+8 == 9 字節(jié) (9 是 最大 對齊數(shù)(1)的 整數(shù)倍) // 這樣寫法,幫我們 避免 了 7 字節(jié) 的 空間浪費};#pragma pack() // 取消設(shè)置的 默認(rèn) 對齊數(shù)// #pragma pack() 一般設(shè)置 默認(rèn) 對齊數(shù) 為 2,4,8, 16 (2的次方數(shù))
?
#include #include struct s{ char c; int i; double d;};int main(){ // offsetof 其實是一個宏,用來表示 成員 相對于 結(jié)構(gòu)體 的 偏移量 printf("%d/n", offsetof(struct s, c));// 0 printf("%d/n", offsetof(struct s, i));// 4 printf("%d/n", offsetof(struct s, d));// 8 return 0; //而且 offsetof 的 參數(shù) 傳的是 一個類型,更加說了 offsetof 是一個宏 }
?
?
#include struct s{ int a; char c; double d;};void init(struct s *tmp){ tmp->a = 100; tmp->c = "w"; tmp->d = 3.14;}void print(struct s tmp)// 傳值:如果傳遞的結(jié)構(gòu)體對象的時候,結(jié)構(gòu)體過大(空間過大),容易導(dǎo)致 參數(shù)壓棧 的 系統(tǒng) 開銷比較大,從而導(dǎo)致系統(tǒng)性能下降。{ printf("%d %c %lf/n", tmp.a, tmp.c, tmp.d);}void print2(const struct s* tmp) // 傳址 : 最好使用這種方法(節(jié)省空間),一個地址在操作系統(tǒng)不改變的情況,永遠(yuǎn)都是4個字節(jié)大小,{ // const 是為了防止 意外改變 結(jié)構(gòu)體變量地址 指向的 值 printf("%d %c %lf/n", tmp->a, tmp->c, tmp->d);}int main() { struct s s = { 0 }; init(&s); print(s); print2(&s); return 0;}
?
?
?
?
?
程序一:
#include struct a // 按照以下寫法寫結(jié)構(gòu)體成員, a 已經(jīng)不是個結(jié)構(gòu)體類型了,而是 一個 位段 類型了// 位段 看見成員 都是 int 類型 ,所以,它 一開始 就創(chuàng)建了 4 byte的 空間{ int a : 2;// 2 這里的意思是: a只需要 2 個比特位(bit) int b : 5;// 5 這里的意思是: b只需要 5 個比特位(bit) int c : 10;// 10 這里的意思是: c只需要 10 個比特位(bit) int d : 30;// 30 這里的意思是: d只需要 30 個比特位(bit)};// 一共 47 個 bit 位,由已經(jīng)創(chuàng)建的 4byte 空間來分配空間, 很明顯 空間不夠 大,只能存入 a,b,c,4 byte 空間 還剩 15 bit d 放不下,怎么辦呢? 在vs 環(huán)境中 系統(tǒng) 會舍棄(浪費)剩余的 15 bit 空間 然后, 它再向 空間申請 4 byte(32bit) 空間, 存儲 d 需要 30 bt 空間,這 30 bit 的數(shù)據(jù) 就存入 這個向系統(tǒng)第二次申請 4 byte 的空間里 至此,數(shù)據(jù)全部存完,剩余的空間就浪費掉了,也就是說 這 位段 的 內(nèi)存大小為 8 byteint main(){ struct a a; printf("%d/n", sizeof(a));// 8 byte return 0;}
&ensp;
?
?
程序一:
#include // vs 環(huán)境struct s // 因為下面 成員類型 為 char 類型,所以它 一開始 就準(zhǔn)備 了 1 byte 空間{ char a : 3;// a 要個 3 bit 位, 由提前準(zhǔn)備 1 byte 空間 來分配,還剩 5 bit // char b : 4;// b 要 4 bit 位,由提前準(zhǔn)備 1 byte 空間 來分配,還剩 1 bit 空間 char c : 5;// c 要 5 bit 位,由提前準(zhǔn)備 1 byte 空間 來分配(剩余 1 bit),不夠大, // 舍棄(浪費)掉,再向內(nèi)存申請 1 byte 的空間 來 存儲 c (剩余 3 bit 空間) char d : 4;// d 需要 4 bit 位,剩余內(nèi)存空間(3 bit)不夠,把 3 bit 浪費掉(舍棄) // 再向內(nèi)存申請 1 byte 空間,來存儲 d,(剩余 4 bit 空間) // 至此 數(shù)據(jù)全部 存儲完畢,剩余的空間 舍棄掉(浪費了) // 一共向內(nèi)存 申請了 3 byte 的空間};int main(){ struct s s = { 0 }; s.a = 10;// 1010 因為 a 只有 3 bit 位 所以存入的是 010 s.b = 20;// 10100 因為 b 只有 4 bit 位 所以存入的是 0100 s.c = 3;// 0011 因為 c 只有 5 bit 位 所以存入的是 00011 s.d = 4;// 0100 因為 d 只有 4 bit 位 所以存入的是 0100 return 0;}
?
?
?
?
?
?
?
?
程序一:
enum sex// 性別{ // 枚舉的可能取值(枚舉常量) male,// 0 female,// 1 secret// 2};enum color // 顏色{ // 枚舉的可能取值(枚舉常量) red,// 0 green,// 1 blue// 2};int main(){ enum day d = mon;//枚舉賦的值,只能是 枚舉的 可能取值 enum sex s = male;//枚舉賦的值,只能是 枚舉的 可能取值 enum color c = blue;//枚舉賦的值,只能是 枚舉的 可能取值 blue 在枚舉的里面 是 2, 那我們 可不可以這樣寫 enum color c = 2 ? 答案是不行,右邊 2 是 int 類型, 左邊的 c 是 enum color 類型 printf("%d %d %d/n", male, female, secret);// 0 1 2 printf("%d %d %d/n", red, green, blue);// 0 1 2 printf("%d/n",sizeof(s)); // 枚舉大小為 4 byte ,為什么呢? 因為 枚舉常量 的類型是 整形, 那 s 就是整形變量,所以輸出為 4 return 0;}
?
?
程序二:
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/119303.html
大家好,我們每天全網(wǎng)搜集各行各業(yè)的研究報告,了解一個行業(yè)從閱讀這個行業(yè)的研報開始,今日分享目錄如下: 20211006分享目錄: 2021抖音電商商家經(jīng)營方法論白皮書-34頁.pdf 2021中國數(shù)據(jù)智能產(chǎn)業(yè)發(fā)展研究報告-50頁.pdf 2021公益數(shù)字化轉(zhuǎn)型-56頁.pdf 2021年中國一線城市出行平臺調(diào)研報告-77頁.pdf 2021年中國內(nèi)容機(jī)構(gòu)(MCN)行業(yè)發(fā)展研究報告-66頁.pd...
摘要:論壇下載由于庫是不帶中值濾波器的,需要自己實現(xiàn),所以花了點時間制作了一個章節(jié)。紅色線是波形高斯白噪聲均勻白噪聲。第版教程發(fā)布中文顯示章節(jié)論壇下載可以直接運行界面效果,也可以使用可以直接編譯運行。上位機(jī)已經(jīng)整合主機(jī),下一版發(fā)布 往期周報匯總地址:http://www.armbbs.cn/for...
摘要:參一江湖只作為內(nèi)容整理方,僅供學(xué)習(xí)使用。更多相關(guān)報告請查看參一江湖星球。 大家好,我們每天全網(wǎng)搜集各行各業(yè)的研究報告,了解一個行業(yè)從閱讀這個行業(yè)的研報開始,今日分享目錄如下: 20210906分享目錄: 2021中國車險科技創(chuàng)新服務(wù)研究報告-45頁.pdf 2021年中國家裝行業(yè)數(shù)字化研...
大家好,我們每天全網(wǎng)搜集各行各業(yè)的研究報告,了解一個行業(yè)從閱讀這個行業(yè)的研報開始,今日分享目錄如下: 20210928分享目錄: 休閑娛樂行業(yè)主題研究:本地出行,眾彩紛呈-35頁.pdf 休閑服務(wù)行業(yè)海南折扣觀察第一期:SKU較少的GDF折扣小幅加大,其他公司相對穩(wěn)定-14頁.pdf 傳媒行業(yè)2021年中期策略報告:從流量到留量,抓住年輕人、擁抱視頻化、提升專業(yè)化-30頁.pdf 傳媒行業(yè)深度...
閱讀 3417·2021-11-25 09:43
閱讀 2301·2021-09-06 15:02
閱讀 3546·2021-08-18 10:21
閱讀 3345·2019-08-30 15:55
閱讀 2352·2019-08-29 17:06
閱讀 3539·2019-08-29 16:59
閱讀 968·2019-08-29 13:47
閱讀 2765·2019-08-26 13:24