sizeof的特殊地位

2021-07-25 03:17:29 字數 3653 閱讀 3093

結構體和共用體的記憶體分配是c語言的乙個難點,也是面試題中的熱點。

示例1:

union data1 

;

sizeof(union data1)的值為16.在編譯器預設設定的情況下,該共用體最大基本型別為double,它佔8位元組,所以此共用體以8來對齊。字元陣列c2佔9個位元組,那麼整個共用體應該佔9個位元組,但按照對齊原則,實際分配給它的記憶體為16位元組。

如果是:

struct data1

;

sizeof(struct data1)的值為24,首先按照儲存大小,該結構體所佔儲存空間為:8+4+1+9=22位元組,這個結構體也是以8對齊,因此實際分配的是24位元組。

示例2:

union data2 

;

sizeof(union data2)的值為12,該共用體占記憶體空間最大的基本資料型別為int,其長度為4,所以該共用體以4來對齊。該共用體的長度取決於字元c2,其長度為9,9不是4的倍數,要進行對齊,因此實際分配的儲存空間為12.

struct data2

;

sizeof(struct data2)的值為16,與上面共用體一樣,該結構體以4對齊。按照儲存大小,該結構體所佔儲存空間為:4+1+9=14,14不是4的倍數,進行對齊,對齊後的值為16.

示例3:

union data3 

;

sizeof(union data3)的值為3,該共用體占記憶體空間最大的基本資料型別為chart,其長度為1,所以該共用體以1來對齊。該共用體的長度取決於字元c2,其長度為3,因此分配的儲存空間為3.

struct data3

;

sizeof(struct data3)的值為3,與上面共用體一樣,該結構體以1對齊。按照儲存大小,該結構體所佔儲存空間為:1+2=3位元組。

示例4:

struct inner

;

這個結構體顯然是8位元組對齊的,在給c1分配儲存空間時,考慮到對齊,分配給c1的位元組數就是8,然後給d分配8位元組,最後給c2分配時,因為也要以8對齊,所以也分配了8個位元組的儲存空間。所以sizeof(struct inner)值為24.

如果是:

struct inner

;

當然這個結構體也是以8位元組對齊的,編譯器編譯程式時,給c1、c2分配儲存空間沒有必要各自給它們分配8位元組,只要8位元組就可以了。給d分配8位元組,所以sizeof(struct inner)值為16.

struct inner

;union data4

;

由於data4共用體中有乙個inner結構體,所以最大的基本資料型別為double,因此以8位元組對齊。共用體的儲存長度取決於t1,而t1長度為24,因此sizeof(union data4)的值為24.

struct inner

;struct data4

;

data4結構體中有乙個inner結構體,所以以8對齊,變數i和c共分配8位元組就可以了,因此sizeof(struct data4)的值為32.

示例5:

struct data

d;

這個結構體所佔的位元組數是多少呢?這裡假設long所佔位元組數為4位元組,short佔2位元組。這個結構體與示例4中第二個struct inner類似。首先這個結構體是以8位元組對齊的,因為最長基本資料型別為double,它佔8位元組,d、e、f、總和為7個位元組。分配儲存空間時,成員 a和b各分配4位元組,d分配4位元組,f分配2位元組,e也分配2位元組。d、e、f總和剛好佔8個位元組,所以sizeof(struct data)值為24.

struct data

d;

sizeof(struct data)值為32.

例1:對於乙個頻繁使用的短小函式,在c語言中最好用什麼實現?

答:最好用巨集定義,這樣可以節省呼叫函式的開銷,效率最高。

例2:已知乙個陣列table,寫乙個巨集定義,求出陣列的元素個數

答:#define ntbl (sizeof(table)/sizeof(table[0]))

對於陣列,sizeof(table)獲取陣列的總長度,而sizeof(table[0])是陣列第乙個元素所佔的長度。當然若是可以用strlen()函式也行。

例3:給定結構

struct a

;

問sizeof(a)的值。

程式分析:unsigned short 一般佔2個位元組,unsigned long一般佔4個位元組,結構體a以4位元組對齊,a中成員t、k、i共佔4+4+8=16位,由於要記憶體對齊,實際那三個成員共佔32位即4位元組,成員m佔4位元組,因此sizeof(a)=8.

例4:求函式返回值,輸入x=9999

int func(int x)

return

count;

}

程式分析:這是統計9999的二進位制形式中有多少個1的函式。9999=9*1024+512+256+15,2*1024的二進位制表示中含有1的 個數為2;512的二進位制表示中含有1的個數為1;256的二進位制表示中含有1的個數為1;15的二進位制表示中含有1的個數為4;故共有1的個數為8,結 果為8 。1000(2)-1(2)=0111(2),正好是原數取反,用這種方法來求1的個數是高效率的。

例5:已知執行這個程式的主機中資料型別long佔8位元組,請分析程式的執行結果。

#include

int main()

d; struct data *p=&d;

printf("%d\n",sizeof(d));

printf("%x\t%x\n",p,p+1);

printf("%x\t%x\n",p,(char *)p+1);

printf("%x\t%x\n",p,(long *)p+1);

return

0; }

執行結果:

32

bffff60 bffff80

bffff60 bffff61

bffff60 bffff64

程式分析:struct data以8個位元組對齊,long型別的成員1分配8個位元組。s、i、c、a原本分別佔4、2、1、10個位元組。由於考慮到對齊,s分配4個位元組,i分配 2個位元組,c分配2個位元組,此時剛好用完8個位元組。a原本分配10個位元組,由於考慮到對齊,要使整個結構體所佔的儲存空間是8的倍數,所以分配給它16個 位元組。因此結構體data佔8+4+4+2+16=32個位元組。

第二條printf語句,p+1中的加1並不是加1個位元組,而是1個struct data的長度,16進製制下,bffff60+20(十進位制數32以十六進製制數表示是20)=bffff80.

第三條printf語句,p+1中的加1,由於對指標p進行了強制型別轉換,使p指向char型別的資料,此時的加1就是加上1個char型別的長度,因此p+1的輸出是bffff61.

第四條語句分析與第三條類似。

《題目雖然簡單,但都值得我們注意!>

微軟的地位

微軟的名聲在歐洲和美國的大學裡,特別是在計算機系裡之壞,大家可能有所耳聞。我認識的 mit,stanford 的教授,貝爾實驗室的專家,甚至乙個歐洲小國的高中計算機老師都絕口不提微軟的名字。在他們眼裡,微軟只是乙個沒有真技術,專靠在落後國家商業宣傳和壟斷經營的小公司。這個 小 並不是說它人少,錢少,...

除錯的重要地位

計算機系統的設計理念決定了除錯的重要地位。現代計算機系統的乙個重要設計原則是讓硬體在軟體的指揮下工作,把靈活性和智慧型留在軟體中實現,這同時也把計算機系統的 控制權交給了軟體。讓軟體控制強大的計算機硬體是聰明的,執行不同的軟體就可以讓同一臺機器做完全不同的事情也是冒險的,一條錯誤的指令就可能讓系統崩...

地位尷尬的北斗導航

上周五在聽了一場關於北斗導航的主題分享演講,感覺北斗導航的地位真是尷尬!全球定位系統是乙個國家重要的空間基礎設施,對於乙個大國而言,發展全球定位系統對於保證國防安全毫無疑問具有重大意義 比如飛彈是否打得準得依靠全球定位系統 北斗導航系統正是基於 的角度來規劃建設的。北斗導航的理想很豐滿 至少在中國市...