1、什麼是sizeof
首先看一下sizeof在msdn上的定義:
the sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). this keyword returns a value of type size_t.
看到return這個字眼,是不是想到了函式?錯了,sizeof不是乙個函式,你見過給乙個函式傳引數,而不加括號的嗎?sizeof可以,所以sizeof不是函式。網上有人說sizeof是一元操作符,但是我並不這麼認為,因為sizeof更像乙個特殊的巨集,它是在編譯階段求值的。舉個例子:
cout<
在編譯階段已經被翻譯為:
cout<<4<
這裡有個陷阱,看下面的程式:
int a = 0;
cout<
輸出為什麼是4,0而不是期望中的4,3???就在於sizeof在編譯階段處理的特性。由於sizeof不能被編譯成機器碼,所以sizeof作用範圍內,也就是()裡面的內容也不能被編譯,而是被替換成型別。=操作符返回左運算元的型別,所以a=3相當於int,而**也被替換為:
int a = 0;
cout<<4<
所以,sizeof是不可能支援鏈式表示式的,這也是和一元操作符不一樣的地方。
結論:不要把sizeof當成函式,也不要看作一元操作符,把他當成乙個特殊的編譯預處理。
2、sizeof的用法
sizeof有兩種用法:
(1)sizeof(object)
也就是對物件使用sizeof,也可以寫成sizeof object 的形式。
(2)sizeof(typename)
也就是對型別使用sizeof,注意這種情況下寫成sizeof typename是非法的。下面舉幾個例子說明一下:
int i = 2;
cout<
可以看出,加()是永遠正確的選擇。
結論:不論sizeof要對誰取值,最好都加上()。
3、資料型別的sizeof
(1)c++固有資料型別
32位c++中的基本資料型別,也就char,short int(short),int,long int(long),float,double, long double
大小分別是:1,2,4,4,4,8, 10。
考慮下面的**:
cout<
unsigned影響的只是最高位bit的意義,資料長度不會被改變的。
結論:unsigned不能影響sizeof的取值。
(2)自定義資料型別
typedef可以用來定義c++自定義型別。考慮下面的問題:
typedef short word;
typedef long dword;
cout<<(sizeof(short) == sizeof(word))<
結論:自定義型別的sizeof取值等同於它的型別原形。
(3)函式型別
考慮下面的問題:
int f1();
double f2()
void f3(){}
cout<
結論:對函式使用sizeof,在編譯階段會被函式返回值的型別取代,
4、指標問題
考慮下面問題:
cout<
可以看到,不管是什麼型別的指標,大小都是4的,因為指標就是32位的實體地址。
結論:只要是指標,大小就是4。(64位機上要變成8也不一定)。
順便唧唧歪歪幾句,c++中的指標表示實際記憶體的位址。和c不一樣的是,c++中取消了模式之分,也就是不再有small,middle,big,取而代之的是統一的flat。flat模式採用32位實位址定址,而不再是c中的 segment:offset模式。舉個例子,假如有乙個指向位址 f000:8888的指標,如果是c型別則是8888(16位, 只儲存位移,省略段),far型別的c指標是f0008888(32位,高位保留段位址,地位保留位移),c++型別的指標是f8888(32位,相當於段位址*16 + 位移,但定址範圍要更大)。
5、陣列問題
考慮下面問題:
char a = "abcdef";
int b[20] = ;
char c[2][3] = ;
cout<
陣列a的大小在定義時未指定,編譯時給它分配的空間是按照初始化的值確定的,也就是7。c是多維陣列,占用的空間大小是各維數的乘積,也就是6。可以看出,陣列的大小就是他在編譯時被分配的空間,也就是各維數的乘積*陣列元素的大小。
結論:陣列的大小是各維數的乘積*陣列元素的大小。
這裡有乙個陷阱:
int *d = new int[10];
cout<
d是我們常說的動態陣列,但是他實質上還是乙個指標,所以sizeof(d)的值是4。
再考慮下面的問題:
double* (*a)[3][6];
cout<
a是乙個很奇怪的定義,他表示乙個指向 double*[3][6]型別陣列的指標。既然是指標,所以sizeof(a)就是4。
既然a是執行double*[3][6]型別的指標,*a就表示乙個double*[3][6]的多維陣列型別,因此sizeof(*a)=3*6*sizeof(double*)=72。同樣的,**a表示乙個double*[6]型別的陣列,所以sizeof(**a)=6*sizeof(double*)=24。***a就表示其中的乙個元素,也就是double*了,所以sizeof(***a)=4。至於****a,就是乙個double了,所以sizeof(****a)=sizeof(double)=8。
C sizeof 使用規則及陷阱分析
1 什麼是sizeof 首先看一下sizeof在msdn上的定義 the sizeof keyword gives the amount of storage,in bytes,associated with a variable or a type including aggregate type...
C sizeof 使用規則及陷阱分析
1 什麼是sizeof 首先看一下sizeof在msdn上的定義 the sizeof keyword gives the amount of storage,in bytes,associated with a variable or a type including aggregate type...
wireshark過濾規則及使用方法
例子 ip.src eq 192.168.1.107 or ip.dst eq 192.168.1.107或者 ip.addr eq 192.168.1.107 都能顯示 ip和目標iptcp.port eq 80 不管埠是 的還是目標的都顯示 tcp.port 80 tcp.port eq 272...