本文目錄一覽:
- 1、C語言中的結構體的大小如何計算
- 2、C語言裡面的字節對齊的計算方法能講解1下嗎?
- 3、C語言,結構體問題?所佔內在字節數,怎麼算的???
- 4、C語言中結構體字節的計算方式
- 5、C語言結構體所佔用的字節數如何計算
C語言中的結構體的大小如何計算
庫函數sizeof();參數是結構體的變量。如果你自己計算的話就是每個結構體成員的大小相加,不同編譯器下是不同的,所以用sizeof()比較好。int
有的編譯器是2字節,有的就是4字節。你舉得例子就是int
2字節+float
4字節+char
1字節。
C語言裡面的字節對齊的計算方法能講解1下嗎?
首先你要知道為什麼會出現字節對齊,這是一種用空間換時間的做法,因為對齊之後可以提高取數的效率。結構體的大小一般是4或者8的倍數,具體是以最大的變量類型的大小為基數的。也就是說在內存中,數據一般是放在一個4的整數倍的起始地址。
sturct S
{
char c;
short s;
int i;
}
它的大小是8個字節,因為前面兩個佔了4字節。如果寫成下面這種形式,它就是12字節了
struct S
{
char c;
int i;
short s;
}
因為為了提高存取效率,所以第一個成員變量佔了四個字節的空間,最後一個成員也佔了四個字節
你非要說計算方法的話要根據具體情況來算了,首先看結構體中哪一個變量所佔的字節數最大,然後後面的對齊計算都以這個為基數(我這裡以4字節為例)。接着,你把每一個成員變量的大小依次相加(按照結構體定義中的順序,從第一個加到最後一個)。當你加到某一個變量的時候,發現超過了4個字節,那麼就把這個變量之前的內容當作是一個整體,它們一共點4個字節,後面的再繼續這個過程
C語言,結構體問題?所佔內在字節數,怎麼算的???
在c語言中如何計算結構體長度和共用體長度?
結構體的長度等於體內各個成員變量長度之後。如此題長度為字符串數組的長度加上兩個int型變量的長度,再加上double長度,最後結果為10+2+2+8=22。解析:char 每個字符佔一個字節(因為是一個十長度的字符數組)所以是10字節,int佔兩個字節,double佔8個字節。所以最後是10+2*2+8=22。
共用體的長度是體內成員中最長的長度。如果一個共用體內最長長度為12字節,則共用體的長度就是12。
希望能夠幫到你。如果還有什麼問題在問?
C語言中結構體字節的計算方式
在說計算方式之前先講講幾個概念一個是 偏移量 還有一個是 內存對齊 。先說偏移量,百度百科對於它的定義是這樣:把存儲單元的實際地址與其所在段的段地址之間的距離稱為段內偏移,也稱為“有效地址或偏移量”。在結構體裡面大概是指結構體變量中成員的地址和結構體變量地址的差。然後再說一下內存對齊這個概念:內存中存放基本類型數據時,計算機的系統會對其位置有限制,系統會要求這些數據的首地址的值是某個數的倍數,而這個數被稱為該數據類型的對齊模數。雖然ANSI C標準中沒有強制規定相鄰聲明的變量內存中要相鄰,但是編譯器會自動幫你處理這個問題,也就是相鄰變量之間可能會填充一些字節。因此在這個問題上又有了編譯器的區別。
那我們先來講講結構體變量在微軟的編譯器的對齊吧
1.結構成員的首地址要是其最寬的基本類型成員的整數倍。編譯器在給結構體分配內存的時候先找到最寬的基本成員,然後再在內存中尋找地址,並將這個最寬的基本數據類型的大小作為對齊模數
2.結構體每一個成員相對於首地址的偏移量是成員大小的整數倍,如果沒有達到這個要求,編譯器會自動填加字節。編譯器在為結構體成員開闢內存的時候會先檢查開闢內存的首地址與結構體變量的首地址之間的偏移量,如果是成員體的整數倍那麼就存放這個變量,不然的話就在這個成員和上一個成員之間填充字節,以達到整數倍的目的
3.結構體所佔的總內存大小要是最大成員體大小的整數倍,如果不是,那麼編譯器會在末尾補充字節。結構體的最後一個成員,不僅要滿足前兩條原則,最後一條準則也要滿足。
接下來來看看幾個例子。
這個結構體在VS 2017下的sizeof的運算結果是12。那麼根據上面的對其規則我們來對其進行計算。
首先是char a。char大小是1,相對於首地址的偏移量是0,然後是int i。int i的大小是4,相對於首地址的偏移量是1,但是1不是4的整數倍,所以編譯器會自動在char a和int i之間填充字節字節。所以in i的偏移量是4。而之後的float b大小4偏移量就是int i的偏移量加上int i的大小故float b的偏移量大小就是8,而8正好是4的倍數那麼就不會有字節填充。而結構體的大小也就自然是最後8+4=12了
從這裡也可以看出結構體大小等於最後一個成員體的大小加上它的偏移量。
那麼我們再來看一個例子
那麼我們再利用之前的算法來對其進行運算,int i的大小是4偏移量是0,int c 的大小是4偏移量是4,double b的大小是8,偏移量是8。char a的大小是1 ,偏移量是16。那麼這個結構體的變量的大小就是16+1=17嗎?答案肯定不是這樣的。在VS的sizeof的運算下這個的結果是24,為什是24呢,那麼這之前說的最後一條原則就要用上了。結構體的大小確實是等於最後一個成員的偏移量加上最後一個成員的大小,但是如果這個結構不滿足是結構體中最大成員大小的整數倍這個條件那麼,編譯器會自動在最後填充字節使其滿足,也就是說,雖然我們計算出的結果是17但是17並不是8的倍數,所以編譯器自動在最後填充字節使其成為8的倍數,即自動擴充成24.、
那我們再來說一下GCC編譯器下的模式。GCC編譯器在Windows環境下用的會比較少,主要在Linux平台下使用GCC編譯器就不遵守微軟的編譯器下的一些準則了,比如之前 說過的對齊模數。微軟的編譯器下的對齊模數是結構體成員中最大的大小而在GCC編譯器下對齊模數最大只能是4。這就意味着對齊模數只能是1,2,4中的一個。因此之前講過的在微軟編譯器下的的一些原則會有些不同。之前講過的成員的首地址的偏移量要是成員大小的整數倍在這裡就有點區別了。在GCC中如果成員大小小於等數4那麼繼續按照之前的標準就好了,但如果大於4,則結構體每個成員相對於結構體首地址的偏移量只能按照是4的整數倍來進行判斷是否添加填充。來看一個簡單的例子。
在這個例子中,如果是按照微軟的編譯器的話計算的結構應該是16,但是在GCC編譯器下是12。道理就是之前講的。
雖然理論上如此但是我自己在試的時候發現上面的運算結果是16,沒錯是16而不是12!為什麼呢?難道是這個理論錯了么,當然不是。我們可以嘗試在GCC下計算一下sizeof(int *)(是int *而不是int)。你會發現結果是8(如果是sizeof(int)那麼結果結果就是4),輸出結果是8那就解決了我們的疑惑。 64位系統的對其長度默認是8而32位的才是4 。這就合理解釋了為什麼計算結果是16而不是12。
對齊模數的選擇只能是基於基本數據類型,所以對於結構體嵌套結構體就不能這麼,至於其的計算方式之後再補充
C語言結構體所佔用的字節數如何計算
結構體的數據類型的有點多我們就不啰嗦了,直接來看相同數據結構體的幾種書寫的格式吧。
格式一:
01.struct tagPhone
02.{
03. char A;
04. int B;
05. short C;
06.}Phone;
格式二:
01.struct tagPhone
02.{
03. char A;
04. short C;
05. int B;
06.}Phone2;
格式三:
01.struct tagPhone3
02.{
03. char A;
04. char B[2];
05. char C[4];
06.}Phone3;
我們都知道,char類型佔用1個字節,int型佔用4個字節,short類型佔用2個字節,long佔用8個,double佔用16個;
那麼我們可能會犯一個錯誤就是直接1+4+2=7,該結構體佔用7個字節。這是錯的。
以下我們簡單分析下:
計算結構體大小時需要考慮其內存布局,結構體在內存中存放是按單元存放的,每個單元多大取決於結構體中最大基本類型的大小。
對格式一:
以int型佔用4個來作為倍數,因為A佔用一個字節後,B放不下,所以開闢新的單元,然後開闢新的單元放C,所以格式一佔用的字節數為:3*4=12;
同理對於格式二,
A後面還有三個字節,足夠C存放,所以C根着A後面存放,然後開闢新單元存放B數據。所以格式二佔用的內存字節為2*4=8.
對於格式三:
上面結構計算大小,sizeof(Phone3) = 1 + 2 + 4 = 7, 其大小為結構體中個字段大小之和,這也是最節省空間的一種寫法。
總結:
第一種寫法,空間浪費嚴重,sizeof 計算大小與預期不一致,但是保持了每個字段的數據類型。這也是最常見的漫不經心的寫法,一般人很容易這樣寫;
第三種寫法,最節省空間的寫法,也是使用 sizeof 求大小與預期一樣的寫法,但是全部使用字節類型,丟失了字段本生的數據類型,不方便使用;
第二種寫法,介於第一種和第三種寫法之間,其空間上比較緊湊,同時又保持了結構體中字段的數據類型。
只要了解是這些寫法的差異性,可以視情況選用。
原創文章,作者:GZOV,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/131065.html