總結常出現的求sizeof值的情況
以前對於c/c++求一些變數的sizeof值很是疑惑,現在經過一段時間的了解,大致有個了解,現在對一些普遍存在,經常要求sizeof值得情況做個總結,整理了很長時間哦!
1. 普通變數的sizeof
普通變數的sizeof值就等於其型別的大小,與變數賦值沒有關係。
例如:int n = 100; sizeof(n) = 4;
double m =123.456 sizeof(m) = 8;
2. 指標變數的sizeof
指標變數的sizeof值與指標所指的物件沒有任何關係,既然是存放位址的,那麼它當然等於計算機內部位址匯流排的寬度。所以在32位計算機中,乙個指標變數的sizeof是4(以位元組為單位),在64位系統中指標變數的sizeof結果為8。
例如:char *pc = 「abc」; sizeof(pc) = 4;
int *pi; sizeof(pi) = 4;
string *ps; sizeof(ps) = 4;
char** ppc = &pc; sizeof(ppc)= 4;
void (*pf) ();(函式指標) sizeof(pf) = 4;
3. 陣列的sizeof
陣列的sizeof值等於陣列所占用的記憶體位元組數。
(3.1)陣列的長度=陣列元素*型別大小
例如:char a1 = 「abc」; sizeof(a1) = 3*1+1=4,注意:字串末尾還存在乙個空字元『\0』
int a2[3] = ; sizeof(a2) = 3*4=12
(3.2)陣列元素個數=陣列長度/型別大小
例如:int c2 = sizeof(a2) /sizeof(int) = 3;
(3.3)陣列「傳址」(陣列為函式引數)
陣列在作為函式引數時,陣列是「傳址」的,呼叫者只需將實參的位址傳遞過去,所以陣列蛻變成指標型別。
例如:void foo1(char a3[3])
sizeof(a3) = 4;
void foo2(char a4)
sizeof(a4) = 4;
4. 結構體的sizeof
在沒有#pragma pack巨集的情況下,遵循以下三條記憶體對齊規則
(1)資料成員對齊規則:結構(struct)裡的資料成員,第乙個資料成員放在offset=0的地方,以後每個資料成員儲存的起始位置要從該成員大小或者成員的子成員(比如陣列,結構體等)大小的整數倍開始。(int在32位機上為4位元組,則要從4的整數倍位址開始儲存)。
(2)結構體作為成員:如果乙個結構體裡有某些結構體成員,則結構體成員要從其內部最大元素大小的整數倍位址開始儲存。(struct a裡存有struct b,b裡有char,int,double等元素,那麼b應該從8的整數倍開始儲存)。
(3)收尾工作:結構體的總大小,也就sizeof的結果,必須是其內部最大成員的整數倍,不足的要補齊。
例如:struct aa
int id; // offset=0,是4的倍數,不用擴大
double weight; // offset=0+4=4不是8的倍數,擴大成offset=8
float height; // offset=8+8=16是4的倍數,不用擴大
// offset=16+4=20不是8的倍數,擴大成offset=24
}aa; //sizeof(aa)=24;
struct bb
char name[2]; // offset=0,是2的倍數,不用擴大
int id; // offset=0+2=2,不是4的倍數,擴大成offset=4
double score; // offset=4+4=8,是8的倍數,不用擴大
short t; // offset=8+8=16,是2的倍數,不用擴大
aa a; // offset=16+2=18,不是24的倍數,擴大成offset=24
// offset=24+24=48,是24的倍數,不用擴大
}bb; // sizeof(bb)=48;
5. 類的sizeof
(5.1) 空類的
sizeof
是1。空類是指沒有成員的類,類中的函式不佔空間,除非是虛函式。
例如:classa
public:
a(){}
~a(){}
void fun(){}
}; // sizeof(a)=1;
(5.2) 若類中包含成員,則類物件的大小只包括其中非靜態成員經過對齊所佔的空間,對齊方式和結構體相同。
例如:class b
public:
int b;
float c;
char d;
}; // sizeof(b)=12;
class c
public:
static int a;
int b;
float c;
char d;
}; // sizeof(c)=12;
(5.3) 在類中包含虛函式,則無論有幾個虛函式,類的大小=資料成員的大小+4。
(因為編譯器會為虛函式生成一張虛函式表,來記錄對應的函式位址,因此在記憶體中只需要儲存乙個指向虛函式表的指標即可,指標大小為4.)
例如:class d
public:
d(){}
~d(){}
int a;
virtual void f(int) {}
virtual void f(double) {}
}; // sizeof(d)=8;
(5.4) 對於子類,它的類大小=父類大小+它的成員大小。(遵循對齊規則)
例如:classa1
public:
inta;
private:
char b;
}; // sizeof(a1) = 8;
class a2 : public a1
public:
char b;
short a;
}; // 8+1+2=11,不是4的倍數,由於對齊原則,sizeof(a2)=12
(5.5) 對於子類和父類中都有虛函式(但是不同的虛函式)的情況,子類的大小是父類的成員加上自己成員的大小,對齊後,再加上4。
例如:classb1
public:
b1(){}
~b1(){}
int a;
virtual voidf(int){}
virtual void f(double){}
class b2 : public b1
public:
b2() {}
int b;
virtual void g(int){}
}; // 4+4=8,是4的倍數,已經對齊,所有sizeof(b2)=8+4=12
(5.6) 對於虛繼承的子類,它的類大小等於父類大小加上它自己成員的大小,再加上它自己乙個指向父類的指標(大小為4),對齊後的sizeof。
例如:class a
private:
int x;
}; // sizeof(a) = 4
class b :virtual public a
private:
int y;
}; // sizeof(b)= 4+4+4=12,是4的倍數,滿足對齊原則
class c : virtual public b
private:
int z;
}; // sizeof(c)= 4+4+4=12,是4的倍數,滿足對齊原則
class d :public b, public c
private:
int m;
}; // sizeof(d)=sizeof(b)+sizeof(c)-b和c相同的部分(a的成員大小,4)+自己的成員大小(4)=24
(5.7) 對於既有虛繼承又有虛函式的子類,其類的大小等於父類大小(包括虛擬表指標,4)加上它自己的大小(包括虛擬表指標,4),再加上它自己乙個指向父類的指標(大小為4),對齊後的sizeof值。
例如:class b1
public:
b1(){}
~b1(){}
virtual voidf(int){}
virtual void f(double){}
}; // sizeof(b1)=4
class b2 : virtual publicb1
public:
b2() {}
virtual void g(int){}
}; // sizeof(b2)=sizeof(b1)+4(自己的大小)+4(指向父類的指標)=12
求解sizeof的值
以下三條規則 資料成員對齊規則 結構 struct 或聯合 union 的資料成員,第乙個資料成員放在offset為0的地方,以後每個資料成員儲存的起始位置要從該成員大小或者成員的子成員大小 只要該成員有子成員,比如說是陣列,結構體等 的整數倍開始 比如int在 位機為 位元組,則要從 的整數倍位址...
sizeof 的結果值
以前一直以為sizeof 就是求乙個陣列的長度,例如乙個陣列a 5 sizeof a 5 現在才發現大錯特錯。實踐出真理,還是直接輸出來的直觀。include include includeusing namespace std struct num struct num1 struct num2 ...
sizeof 聯合 值的理解
sizeof 聯合 值的理解 先來看各種型別在記憶體中所占用的空間大小 include int main void 執行結果 單位是位元組 int sizeof 4 char sizeof 1 float sizeof 4 double sizeof 8 再寫乙個聯合的例子,並列印出最終值 incl...