int a;
sizeof(a); // = 4
sizeof(int); // = 4
sizeof(1); // = 4
void fn()
sizeof(fn); // error:函式
sizeof(fn()); // error:不能確定型別
struct s
; s sa;
sizeof( sa.a ); // error:位域成員
int a = -1;
sizeof(a=3); // = sizeof(a) = sizeof(int) = 4
cout<
sizeof(int); // = 4
sizeof(double); // = 8
sizeof(char); // = 1
sizeof(bool); // = 1
sizeof(short); // = 2
sizeof(float); // = 4
sizeof(long); // = 4
sizeof(int *); // = 4
sizeof(double *); // = 4
sizeof(char *); // = 4
2.3.1 陣列的sizeof返回整個陣列所佔的位元組數,即(陣列元素個數×每個元素所佔位元組)。int ai = ;
sizeof(ai); // = 2*4 = 8
2.3.2 常量字串與字元陣列的記憶體分配方式相同。
char ac = "abcd"; //注意陣列末尾的字串終結符'\0'
sizeof(ac); // = 5*1 = 5
sizeof("abcd"); // = 5*1 = 5
2.3.3 陣列和指標所佔的位元組數不同,應注意區分。int *pi = new int[10]; //這是指標
sizeof(pi); // = 4
int ai[10];
int *p = ai; //這還是指標
sizeof(p); // = 4
double* (*a)[3][6]; //看成(double *) (*a)[3][6],即乙個3×6的二維陣列,陣列元素為指標,指向double型別。
sizeof(a); // = 4,a為指向上述二維陣列的指標
sizeof(*a); // = sizeof(double *)*3*6 = 72,*a表示上述二維陣列
sizeof(**a); // = sizeof(double *)*6 = 24,**a即*(*a),表示double*[6],是元素為double指標的一維陣列。
sizeof(***a); // = sizeof(double *) = 4,表示上述一維陣列中的第乙個元素,元素型別為double指標。
sizeof(****a); // = sizeof(double) = 8,表示上述陣列首元素指向的double型別。
2.3.4 函式形式引數中的陣列會蛻變為指標,原因是陣列引數「傳址呼叫」,呼叫者只需將實參的位址傳遞過去。有一種情況例外,那就是引數是指向陣列的指標。void acf(char p[3]) //引數型別是int,表示指向int的指標
void aif(int p) //引數型別是int,表示指向int的指標
void pif(int (*p)[6]) //引數型別是int (*)[6],表示指向int陣列的指標
void ppf(int *p[6]) //引數型別是int *,表示指向int指標的指標
2.4.1 空類或空結構體占乙個位元組。class cempty ;
sizeof(cempty); // = 1
struct sempty ;
sizeof(sempty); // = 1
2.4.2 非空類和結構體所佔位元組為所有成員佔位元組的和,但是不包括成員函式和靜態成員所佔的空間。
class cint : public cempty ;
sizeof(cint); // = 4;
class cfunc
};sizeof(cfunc); // = 1;
struct sint : sempty ;
sizeof(sint); // = 1;
2.4.3 位元組對齊
為了加快計算機的取數速度,編譯器預設對記憶體進行位元組對齊。對結構體(包括類)進行位元組對齊的原則是:
1)結構體變數的首位址能夠被其最寬基本型別成員的大小所整除;
2)結構體每個成員相對於結構體首位址的偏移量(offset)都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充位元組(internal adding);
3)結構體的總大小為結構體最寬基本型別成員大小的整數倍,如有需要編譯器會在最末乙個成員之後加上填充位元組(trailing padding)。
struct sbyte1
; sizeof(sbyte1); // = 16
struct sbyte2
; sizeof(sbyte2); // = 24,為了湊成8的倍數,填充20~23
另外,可以通過#pragma pack(n)來設定變數以n位元組對齊方式。
#pragma pack(push) //儲存對齊狀態
#pragma pack(4) //設定為4位元組對齊
class cbyte
;#pragma pack(pop) //恢復對齊狀態
sizeof(cbyte); // = 16
2.4.4 位域
有些資訊在儲存時,並不需要占用乙個完整的位元組, 而只需佔幾個或乙個二進位制位。例如在存放乙個開關量時,只有0和1 兩種狀態,用一位二進位即可。為了節省儲存空間,並使處理簡便,c語言又提供了一種資料結構,稱為「位域」或「位段」。所謂「位域」是把乙個位元組中的二進位劃分為幾個不同的區域, 並說明每個區域的位數。
2.4.4.1 位域以位元位作為單位,其長度不能大於乙個位元組。乙個位域必須儲存在同乙個位元組中,如乙個位元組所剩空間不夠存放另一位域時,應從下一單元起存放該位域。
struct sbit1
;sizeof(sbit1); // = (3+4+1+5+3) bits = 2 bytes
2.4.4.2 使用空域可以有意使某位域從下一單元開始,但是空域不能使用。
sizeof(sbit2); // = (3+4+1+5+3) bits = 3 bytes
struct sbit2
;sizeof(sbit2); // = (3+4+1+5+3) bits = 3 bytes
2.4.4.3 如果相鄰的位域字段的型別不同,則各編譯器的具體實現有差異,vc6採取不壓縮方式,dev-c++採取壓縮方式。struct sbit3
;sizeof(sbit3); // = 6 bytes,由於相鄰位域型別不同,在vc6中其sizeof為6,在dev-c++中為2。
2.4.4.4 如果位域字段之間穿插著非位域字段,則不進行壓縮。struct sbit4
;sizeof(sbit4); // = 8 bytes
2.4.4.5 整個結構體的總大小為最寬基本型別成員大小的整數倍;
sizeof(sbit5); // = 12 bytes
聯合表示若干資料成員取其一,故以疊加方式分配記憶體,所佔位元組數為最大資料成員所佔的位元組數。
cpp**
union u
;
sizeof(u); // = max(sizeof(i), sizeof(c), sizeof(d)) = sizeof(d) = 8
計算機深入理解 一
1.1 匯流排 匯流排是用來在計算機各個部件中傳遞資料的快遞員,這個快遞員攜帶的資料是有限制的通常是4個位元組32位,8個位元組64位。1.2 io 裝置 io 裝置是計算機與外界資料交換的快遞員。包括四個功能不一的快遞員 1 作為使用者輸入的鍵盤和滑鼠 2 作為使用者輸出的顯示器 3 用來長期儲存...
深入理解計算機筆記1
第一章 本書可以使你成為鳳毛麟角的權威程式設計師。1系統中的所有資訊都是由一串二進位制表示的,區分不同資料物件的唯一方法是我們讀到這些資料物件時的上下文。比如10000110,可以是乙個無符號數,也可以是乙個有符號數,還可以是乙個ascii碼,還可能是一條指令。2編譯系統包括了預處理器 編譯器 彙編...
深入理解計算機系統
關鍵路徑是在迴圈的反覆執行中形成的資料相關鏈。迴圈展開是一種程式變換,通過增加每次迭代計算的元素的數量,減少迴圈的迭代次數。重新結合變換能夠減少計算中關鍵路徑上操作的數量,通過更好地利用功能單元的流水線能力得到更好的效能。浮點運算不保證是可結合的,通常迴圈展開和並行地累積在多個值中,是提高程式效能的...