欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言詳解結(jié)構(gòu)體的內(nèi)存對(duì)齊與大小計(jì)算

 更新時(shí)間:2022年04月23日 17:03:27   作者:CodeWinter  
C 數(shù)組允許定義可存儲(chǔ)相同類型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是 C 編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許你存儲(chǔ)不同類型的數(shù)據(jù)項(xiàng),本篇讓我們來(lái)了解C 的結(jié)構(gòu)體內(nèi)存對(duì)齊與計(jì)算大小

結(jié)構(gòu)體的內(nèi)存對(duì)齊

1、計(jì)算結(jié)構(gòu)體的大小

struct S1
{
	char c1; // 1 byte,默認(rèn)對(duì)齊數(shù)為8,所以c1的對(duì)齊數(shù)是1,第一個(gè)成員變量放在與結(jié)構(gòu)體變量偏移量為0的地址處
	int i;   // 4 byte,默認(rèn)對(duì)齊數(shù)為8,所以i的對(duì)齊數(shù)是4,所以i要放到偏移量為 4的整數(shù)倍 的地址處
	char c2; // 1 byte,默認(rèn)對(duì)齊數(shù)為8,所以c2的對(duì)齊數(shù)是1,所以c2要放到偏移量為 1的整數(shù)倍 的地址處
	//最大對(duì)齊數(shù)是4
	//成員大小為9,不是最大對(duì)齊數(shù)4的整數(shù)倍,所以結(jié)構(gòu)體總大小為12
};
printf("%d\n", sizeof(struct S1));

原理分析:

【練習(xí)題】

// 練習(xí)1
struct S2
{
	char c1;  // 1 byte / 8,對(duì)齊數(shù)是1,
	char c2;  // 1 byte / 8,對(duì)齊數(shù)是1,
	int i;    // 4 byte / 8,對(duì)齊數(shù)是4,
	// 最大對(duì)齊數(shù)是4
	// 成員大小為8,是最大對(duì)齊數(shù)的整數(shù)倍,所以結(jié)構(gòu)體總大小為8
};
printf("%d\n", sizeof(struct S2));

// 練習(xí)2
struct S3
{
	
	char c;   // 1/8,對(duì)齊數(shù)是1
	int i;    // 4/8,對(duì)齊數(shù)是4
	double d; // 8/8,對(duì)齊數(shù)是8
	// 最大對(duì)齊數(shù)是8
	// 成員大小為16,是最大對(duì)齊數(shù)的整數(shù)倍,所以結(jié)構(gòu)體總大小為16
};
printf("%d\n", sizeof(struct S3));

// 練習(xí)3-結(jié)構(gòu)體嵌套問題
struct S4
{
	char c1;      //  1/8,對(duì)齊數(shù)是1
	struct S3 s3; // 16 byte,【S3的最大對(duì)齊數(shù)是8】,所以s3要放到8的整數(shù)倍的地址處
	double d;     //  8/8,對(duì)齊數(shù)是8
	// 最大對(duì)齊數(shù)是8
	// 成員大小為32,是最大對(duì)齊數(shù)的整數(shù)倍,所以結(jié)構(gòu)體總大小為32
};
printf("%d\n", sizeof(struct S4));

2、結(jié)構(gòu)體的對(duì)齊規(guī)則

第一個(gè)成員變量在與結(jié)構(gòu)體變量偏移量為 0 的地址處。

其他成員變量要對(duì)齊到某個(gè)數(shù)字(對(duì)齊數(shù))的整數(shù)倍的地址處。

  • 對(duì)齊數(shù) =「編譯器默認(rèn)的一個(gè)對(duì)齊數(shù)」與「該成員大小」中的較小值。
  • VS中默認(rèn)對(duì)齊數(shù)為「8」,Linux中沒有對(duì)齊數(shù)

結(jié)構(gòu)體總大小為:最大對(duì)齊數(shù)(每個(gè)成員變量都有一個(gè)對(duì)齊數(shù))的整數(shù)倍。

如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對(duì)齊到自己的最大對(duì)齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對(duì)齊數(shù)(含嵌套結(jié)構(gòu)體的對(duì)齊數(shù))的整數(shù)倍。

3、為什么存在內(nèi)存對(duì)齊?

大部分的參考資料是這樣說(shuō)的:

  • 平臺(tái)原因(移植原因): 不是所有的硬件平臺(tái)都能訪問任意地址上的任意數(shù)據(jù)的;某些硬件平臺(tái)只能在某些地址處取某些特定類型的數(shù)據(jù),否則拋出硬件異常。(那我們就要將數(shù)據(jù)對(duì)齊到能夠訪問的這些地址處)
  • 性能原因:數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對(duì)齊。 原因在于,為了訪問未對(duì)齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問;而對(duì)齊的內(nèi)存訪問僅需要一次訪問。

4、總結(jié)

結(jié)構(gòu)體的內(nèi)存對(duì)齊是拿空間來(lái)?yè)Q取時(shí)間的做法。

思考:那在設(shè)計(jì)結(jié)構(gòu)體的時(shí)候,我們既要滿足對(duì)齊,又要節(jié)省空間,如何做到:

讓占用空間小的成員盡量集中在一起。

// 例如:
struct S1
{
	char c1;  // 1/8,對(duì)齊數(shù)是1
	int i;    // 4/8,對(duì)齊數(shù)是4
	char c2;  // 1/8,對(duì)齊數(shù)是1
	// 最大對(duì)齊數(shù)是4
	// 成員大小為9,不是最大對(duì)齊數(shù)的整數(shù)倍,所以結(jié)構(gòu)體總大小為12
};

struct S2
{
	char c1;  // 1/8,對(duì)齊數(shù)是1
	char c2;  // 1/8,對(duì)齊數(shù)是1
	int i;    // 4/8,對(duì)齊數(shù)是4
	// 最大對(duì)齊數(shù)是4
	// 成員大小為8,是最大對(duì)齊數(shù)的整數(shù)倍,所以結(jié)構(gòu)體總大小為8
};

S1和S2類型的成員一模一樣,但是S1和S2所占空間的大小卻有了一些區(qū)別。

到此這篇關(guān)于C語(yǔ)言詳解結(jié)構(gòu)體的內(nèi)存對(duì)齊與大小計(jì)算的文章就介紹到這了,更多相關(guān)C語(yǔ)言結(jié)構(gòu)體內(nèi)存對(duì)齊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • QT串口通信的實(shí)現(xiàn)方法

    QT串口通信的實(shí)現(xiàn)方法

    如果用qt寫程序作為上位機(jī),然后通過和usb和下位機(jī)通信的時(shí)候,就需要用到qt中的串口通信了。本文介紹了QT串口通信的實(shí)現(xiàn)方法,感興趣的小伙伴們可以參考一下
    2021-05-05
  • 詳解C++循環(huán)創(chuàng)建多級(jí)目錄及判斷目錄是否存在的方法

    詳解C++循環(huán)創(chuàng)建多級(jí)目錄及判斷目錄是否存在的方法

    這篇文章主要介紹了C++循環(huán)創(chuàng)建多級(jí)目錄及判斷目錄是否存在的方法,文中代碼有一個(gè)針對(duì)各種系統(tǒng)進(jìn)行判斷來(lái)加載不同頭文件的方法,需要的朋友可以參考下
    2016-03-03
  • C++控制臺(tái)繪圖頭文件實(shí)例代碼

    C++控制臺(tái)繪圖頭文件實(shí)例代碼

    控制臺(tái)(console)是電腦的最基本交互接口,通常包括鍵盤(keyboard)和屏幕(screen),下面這篇文章主要給大家介紹了關(guān)于C++控制臺(tái)繪圖頭文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • 基于Matlab實(shí)現(xiàn)山脊圖的繪制

    基于Matlab實(shí)現(xiàn)山脊圖的繪制

    這篇文章主要介紹了如何利用Matlab實(shí)現(xiàn)山脊圖的繪制,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Matlab有一定的幫助,需要的可以參考一下
    2022-05-05
  • C++求四個(gè)正整數(shù)最大公約數(shù)的方法

    C++求四個(gè)正整數(shù)最大公約數(shù)的方法

    這篇文章主要介紹了C++求四個(gè)正整數(shù)最大公約數(shù)的方法,涉及C++求余算法的運(yùn)用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2016-05-05
  • C++ Boost Intrusive庫(kù)示例精講

    C++ Boost Intrusive庫(kù)示例精講

    Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱
    2022-11-11
  • 詳談C語(yǔ)言指針

    詳談C語(yǔ)言指針

    這篇文章主要介紹了C語(yǔ)言的指針,介紹了其相關(guān)概念,然后分享了幾種用法,具有一定參考價(jià)值。需要的朋友可以了解下
    2021-10-10
  • 使用C語(yǔ)言打印月歷

    使用C語(yǔ)言打印月歷

    這篇文章主要為大家詳細(xì)介紹了使用C語(yǔ)言打印月歷,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C++編程中用put輸出單個(gè)字符和cin輸入流的用法

    C++編程中用put輸出單個(gè)字符和cin輸入流的用法

    這篇文章主要介紹了C++編程中用put輸出單個(gè)字符和cin輸入流的用法,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • C語(yǔ)言實(shí)現(xiàn)五子棋人人對(duì)戰(zhàn)

    C語(yǔ)言實(shí)現(xiàn)五子棋人人對(duì)戰(zhàn)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)五子棋人人對(duì)戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12

最新評(píng)論