對於c語言開發人員來說,sizeof應該不陌生吧。此次我主要寫的是sizeof對各變數長度的計算方式。
sizeof這個函式主要是對各資料型別的長度進行計算,入參為資料型別,返回值計算結果。但由於不同os的系統架構下,sizeof計算的結果會存在一定的差異。下文主要基於32位系統,討論sizeof的計算方式。
比較常見的場景是基本資料型別長度的計算結果如下:
型別
32位系統(bytes)
64位系統(bytes)
bool
1
1
char
1
1
short
2
2
int
4
4
long
4
8
long long
8
8
char *
4
8
float
4
4
double
8
8
long double
12
16
說明:char*代表指標變數,不管什麼型別的指標,指標變數長度都是一樣的。
為了加快cpu取數速度,c標準規定
變數存放位址一定為自身長度的整數倍。因此變數間就會出現縫隙空間,這時編譯器在編譯期間就會對這些縫隙進行填充,叫做變數的對齊與補齊規則。接下來我會舉例說明各種場景下的對齊與補齊方式:
例1:#include
struct st ;
int main(void)
執行結果:
&tmp=0xbfe6e960
&tmp.a=0xbfe6e960
&tmp.b=0xbfe6e964
&tmp.c=0xbfe6e968
&tmp.d=0xbfe6e96c
sizeof(tmp)=16
從結果可以出成員變數的存放位址都是自身長度的整數倍。但結構體有所不同,結構體變數的位址應該為其最大成員變數長度的整數倍,且各成員變數遵守對齊與補齊規則,包括最後乙個成員變數。所以 st結構體的大小為:1(a)+3(填充)+4(b)+2(c)+2(填充)+4(d)=16
例2:struct st
;結果:
sizeof(tmp)=16
在c++中可能會見到結構體中定義靜態成員的**,由於靜態成員在定義時就已經分配的記憶體空間,所以用sizeof來計算結構體大小時,是不計算在內的。
例3:struct st1
tmp1;
結果:sizeof(st1)=0
空結構體的大小為0,該型別不占用任何的位址空間。
例3:void fun(void)
printf("sizeof(void)=%d\n",sizeof(void));
printf("sizeof(fun)=%d\n",sizeof(fun));
printf("sizeof(fun())=%d\n",sizeof(fun()));
結果:sizeof(void)=1
sizeof(fun)=1
sizeof(fun())=1
void型別的大小為1,sizeof也可以用來計算函式的大小以及返回值。
從執行檔案的頭部資訊來看:
num: value size type bind vis ndx name
48: 080483c4 5 func global default 13 fun
函式fun應該是占用5個位元組的,這裡不知道為什麼列印出來只有1個位元組?不過一般不會用sizeof來計算函式大小,沒有什麼意義。
例4:struct st2
; 結果:sizeof(st2)=4
這個例子結合位變數來說明位元組對齊與補齊的規則,結構體中各成員變數存放如下:
|0|1234|567 01234567 01234567 01234567| //4個位元組長度
|a| b | | c | | d | //4個變數存放
首先a占用了第乙個位元組的最低位,b占用了第1到第4位,由於c所佔的位數超過了上一位元組空閒的位數,所以c從下一位元組的位址開始算起,占用第0到第4位。變數d由於是short型變數,需要以2位元組對齊,所以位址從第3個位元組的低位開始算,長度為10,餘下6個位自動補齊。最終,該結構體大小為4位元組。
例5:union st2
;結果:
sizeof(union)=4
聯合體中成員是共享記憶體的,所以長度為最大成員變數的大小。
例6:struct st
; struct st2
; struct st4
;結果:
sizeof(st4)=24
在st4結構體中,成員a占用16個位元組,成員b占用6個位元組,為什麼 最終st4會占用24個位元組呢?原因是a中變數最大長度為4,所以a以4位元組對齊,b中變數最大長度為2,所以b以2位元組對齊,但對於st4結構體來說,它內部基本資料型別最長為4位元組,所以st4結構體以4位元組對齊,最後會在後面填充2個位元組。
總之,sizeof計算規則如下:
1、基本資料型別變數位址為自身長度的整數倍
2、對於結構體,sizeof會把編譯器自動填充的位元組算在內。
3、sizeof不計算靜態變數的長度
c語言提供了#pragma巨集可以指定位元組對齊的長度:
例7:#include
#pragma pack(2)
//強制以2位元組對齊
struct st
; void main(void)
結果:sizeof(struct st)=6
st結構體中成員b的初始位址不再是4的位數,而是2的倍數。
C語言 sizeof和strlen的計算
sizeof是乙個關鍵字,求字串所佔的位元組數。printf d n sizeof int printf d n sizeof a printf d n sizeof a strlen是乙個函式,求字串的長度,結束符 0之前的字元個數。看一下下面幾組練習 一維陣列 int a printf d n ...
c語言中結構的sizeof如何計算
演算法思路 1.offset設定為0.offset就是分配空間的偏移量 2.依次對結構裡面的每個成員p進行下面的計算。如果計算完畢,跳到第7步。2.計算temp min p的對齊引數,系統對齊引數 p如果是內建資料型別,對齊引數有編譯器給出。比如char的對齊引數是1等等。系統對齊引數由 pragr...
c語言中的sizeof
一 sizeof的概念 sizeof是c語言的一種單目操作符,如c語言的其他操作符 等。它並不是函式。sizeof操作符以位元組形式給出了其運算元的儲存大小。運算元可以是乙個表示式或括在括號內的型別名。運算元的儲存大小由運算元的型別決定。二 sizeof的使用方法 1 用於資料型別 sizeof使用...