結構體型別的長度計算,C語言中結構體陣列長度怎麼計算

時間 2022-04-06 16:52:43

1樓:等待的幸福快樂

計算方法:

運算子sizeof可以計算出給定型別的大小,對於32位系統來說,sizeof(char) = 1; sizeof(int) = 4。基本資料型別的大小很好計算,我們來看一下如何計算構造資料型別的大小。

c語言中的構造資料型別有三種:陣列、結構體和共用體。

陣列是相同型別的元素的集合,只要會計算單個元素的大小,整個陣列所佔空間等於基礎元素大小乘上元素的個數。

結構體中的成員可以是不同的資料型別,成員按照定義時的順序依次儲存在連續的記憶體空間。和陣列不一樣的是,結構體的大小不是所有成員大小簡單的相加,需要考慮到系統在儲存結構體變數時的位址對齊問題。看下面這樣的乙個結構體:

struct stu1

;先介紹乙個相關的概念——偏移量。偏移量指的是結構體變數中成員的位址和結構體變數位址的差。結構體大小等於最後乙個成員的偏移量加上最後乙個成員的大小。

顯然,結構體變數中第乙個成員的位址就是結構體變數的首位址。因此,第乙個成員i的偏移量為0。第二個成員c的偏移量是第乙個成員的偏移量加上第乙個成員的大小(0+4),其值為4;第三個成員j的偏移量是第二個成員的偏移量加上第二個成員的大小(4+1),其值為5。

實際上,由於儲存變數時位址對齊的要求,編譯器在編譯程式時會遵循兩條原則:一、結構體變數中成員的偏移量必須是成員大小的整數倍(0被認為是任何數的整數倍) 二、結構體大小必須是所有成員大小的整數倍。

對照第一條,上面的例子中前兩個成員的偏移量都滿足要求,但第三個成員的偏移量為5,並不是自身(int)大小的整數倍。編譯器在處理時會在第二個成員後面補上3個空位元組,使得第三個成員的偏移量變成8。

對照第二條,結構體大小等於最後乙個成員的偏移量加上其大小,上面的例子中計算出來的大小為12,滿足要求。

再看乙個滿足第一條,不滿足第二條的情況

struct stu2

;成員k的偏移量為0;成員t的偏移量為4,都不需要調整。但計算出來的大小為6,顯然不是成員k大小的整數倍。因此,編譯器會在成員t後面補上2個位元組,使得結構體的大小變成8從而滿足第二個要求。

由此可見,大家在定義結構體型別時需要考慮到位元組對齊的情況,不同的順序會影響到結構體的大小。對比下面兩種定義順序

struct stu3

struct stu4

雖然結構體stu3和stu4中成員都一樣,但sizeof(struct stu3)的值為12而sizeof(struct stu4)的值為8。

如果結構體中的成員又是另外一種結構體型別時應該怎麼計算呢?只需把其即可。但有一點需要注意,後的結構體的第乙個成員的偏移量應當是被的結構體中最大的成員的整數倍。看下面的例子:

struct stu5

ss;int k;

}結構體stu5的成員ss.c的偏移量應該是4,而不是2。整個結構體大小應該是16。

如何給結構體變數分配空間由編譯器決定,以上情況針對的是linux下的gcc。其他平台的c編譯器可能會有不同的處理。

2樓:匿名使用者

不能像樓主這樣解釋,計算結構體的長度,不能忽略乙個引數:

#pragma pack(8); //這個8是結構體預設的對齊引數,其作用是:

1>當結構體中有變數型別佔的長度比這個大,那麼該結構的對齊引數就是8;

2>如果結構體中成員的型別都比這個預設值小,那麼該結構體的對齊引數就是該結構體中占用空間最長的成員變數的長度,如instruct a;的對齊長度是1(字元變數佔1個位元組)

根據樓主的輸出,樓主的執行環境pack(4),因為a中double佔的字元大於4,所以結構體a的對齊引數為4,那麼結果就是4+4+4,實際後面兩個4是存乙個double資料;第二題int a;已經等於4,所以對齊變數為4。

當知道對齊規則後,那麼記憶體是怎麼排列的呢?

定義變數的時候先找到乙個記憶體位址,根據計算機的內部結構(我還不是很清楚),會選用乙個可用的,而且對對齊變數求余為0的位址作為儲存該結構體的位址。

如2題既然對齊變數為4,那麼一定會選乙個4的整數倍的位址作為儲存這個結構體的起始位址,

然後是10個char型別,佔10個位元組,此時,下面的位址已經不能整除4了,比如8+10=18已經不能整除4,所以會空2個位元組,從20開始儲存int,正好4個位元組,位址變為24,能被4整除,也就是char s[10]和int a,占用了12(有2個空位元組)+4=16個位元組,由於int a後的位址能被4整除,所以a k,的長度就是a的長度為12,所以b的長度為28。

你可以#pragma pack(8);來修改預設的對齊引數來測試。

3樓:匿名使用者

這個問題確實有點糾結,但不是沒有規律。

首先求位元組長度用sizeof(...)

#include

int main()

;struct b;

int a=sizeof(a);

int b=sizeof(b);

printf("%d%d",a,b);

}輸出16,32而不是12,26.

預設對齊,應該是以struct的最大元素為對齊基數,也就是(double)8的倍數(第二個b為16的倍數。

正如三樓」所說在定義結果體的時候最好把相同型別的成員放到一起,可以節省空間「

具體lz可以去試試。

c語言中結構體陣列長度怎麼計算

4樓:卑長征眭歌

結構體陣列的長度計算方法和普通陣列相同。

1、c語言中,定義陣列後可以用sizeof命令獲得陣列的長度(即可容納元素個數)。但是通過傳遞陣列名引數到子函式中,以獲得陣列長度是不可行的,因為在子函式當中,陣列名會退化為乙個指標。

2、例如:

intdata[4],length;

length=sizeof(data)/sizeof(data[0]);

//陣列佔記憶體總空間除以單個元素佔記憶體空間大小,即等於元素個數printf("length

ofdata[4]=%d",

length

);//輸出length

ofdata[4]=4

c語言結構體型別,C語言結構體型別

遞迴是呼叫自身,資料結構裡的鍊錶定義裡邊是結構體指標,而非結構體自身,不是遞迴呼叫。線性表單鏈表並沒有遞迴呼叫啊,他是用指標指向下乙個鍊錶struct lnode next 你去在理解下遞迴思想。呵呵,前面的都沒說到問題的本質.建議你先去了解下什麼是指標,什麼是指標變數.因為指標變數是存放指標的,並...

怎麼用順序線性表儲存結構體型別的資料

將儲存資料部分的動態陣列部分定義。成結構體型別的就可以了。c語言,老師問了乙個問題 為什麼在定義結構體變數之前,必須先定義結構體型別?定義變數,就是在記憶體中申請空間,資料型別就與系統的約定,按照什麼樣的資料型別的儲存格式和計算邏輯對待。所以定義變數都需要指明型別,比如int a 就是指明int型。...

c語言結構體初始化,C語言結構體裡的結構體怎麼初始化

你已經定義了乙個mem1,下一句又定義了乙個mem1,所以它會提示你多次定義了,應該把第二個struct mem去掉吧 struct mem mem1 變成 mem1 估計是vc6.0 把它當做c 來處理了 一眼就看出問題了。去掉倒數第三行 mem1 前面的struct mem 就解決了 c語言結構...

結構體賦值,給結構體中的變數賦值

結構體賦值應該不結構體中的所有項都賦過去例如 struct node node s1,s2 如果將s2的值付給s1則 s1 data s2 data s1 next s2 next 這樣才叫結構體的賦值。每一部分都要賦值 s1 s2放編譯器試試就知道是可以的 typedef structaa voi...

mysql 字段型別 varchar 的長度??

varchar資料型別所支援的最大長度也是255個字元。1個漢字字元儲存需要2個位元組,即255 2 127 1個英文本元儲存需要1個位元組,即255 其實要看編碼的。utf8以可變位元組數 1 3位元組 來儲存每個字元char 10 就是30位元組。varchar 10 就是10 30位元組。my...