很多人認為sizeof是乙個函式,這是從它的用法看出來的,因為我們用的時候一般會寫成sizeof(),確實像函式。但sizeof其實是操作符,返回乙個物件或者型別在當前平台下所佔的記憶體位元組數。
首先我們來看乙個例子,注意本機使用平台為64位系統
#includeint main(void)
輸出結果是
1
10 1 8
現在來逐行分析該結果:
(1)ch[1]是乙個char型,char型所佔的記憶體空間為1位元組。
(2)ch指向的是整個char陣列,你或許可以這樣理解ch,char[10] ch(因為字元陣列最後有個'\0'),所以sizeof(ch)大小是10
(3)第三條語句,第一眼一看似乎是個bug,ptr指向ch陣列,那麼 ptr+100 豈不是越界訪問,因為ch字元陣列本身大小只有10個位元組。其實這並不是個bug,前面提到過sizeof是運算子,它計算的是變數或型別所佔的記憶體空間大小,這意味著它並不需要實際訪問 ptr+100 這個實際位址,而判斷它是字元即可(因為ptr指向的是ch字元陣列,自然認為*(ptr+100)是字元),所以輸出為1毫不奇怪,後面還會講到一些sizeof的使用誤區。
(4)ptr是乙個指標。指標是什麼?指標表示的是乙個物件在記憶體中的位址。既然是位址,必然要和作業系統的位址匯流排表示一致,而位址匯流排通常和字長一樣。所以在32位作業系統下,乙個指標必然是4個位元組,而64位作業系統下是8個位元組。
還是先來看乙個例子
int i=3;
printf("%lu\n",sizeof(i++));
printf("%d\n",i);
return 0;
沒錯,程式輸出結果是
4
3
可能會奇怪為什麼語句裡面的 i++ 沒有執行,這又回到我們最初的定義上來了。sizeof計算的是所占用記憶體空間的大小,當它得知sizeof(i++)裡面是乙個整形變數時,也就知道了所佔空間的大小,也就無需計算 i++了。從某種程度上說,這和我們上面說過的 那個 *(ptr+100)有些類似之處。
最後讓我們看乙個稍微複雜一點的例子。
int a(char a[10])
int main()
這個問題有些複雜,首先要理解陣列名雖然指向的是陣列的起始位址,但和指向該位址的指標還是不一樣的。不一樣在**?就如上面所說的,char a[10]理解成char[10] a; a是指向乙個大小為10的陣列,所以sizeof(a)就是10。但呼叫a()函式的時候情況有些不一樣,傳遞引數的時候並不是作為乙個陣列名而是退化成了乙個指標,在32位機下就是4個位元組,所以答案應該就是10*10+4*2=108
徹底理解多型
父類引用或者介面的引用指向了自己的子類物件。animal a new cat 父類可以呼叫子類中覆寫過的 父類中有的方法 多型的好處 提高了程式的擴充套件性。繼承的父類或介面一般是類庫中的東西,如果要修改某個方法的具體實現方式 只有通過子類去覆寫要改變的某乙個方法,這樣在通過將父類的應用指向子類的例...
徹底理解記憶體概念
儘管記憶體這個詞常常掛在我們的嘴上,但是,有多少人真正了解記憶體 理解記憶體概念呢?對剛剛步入電腦世界的初學者來說,基本記憶體 上位記憶體 高階記憶體 擴充套件記憶體 擴充記憶體 保留記憶體等概念更是玄之又玄,難以徹底理解。所以我們特地介紹一下記憶體的基本概念。基本知識 記憶體 記憶體就是儲存程式以...
徹底理解Python切片
徹底理解python切片 wyf部落格 list insert ind,value 在ind元素前面插入value 首先對ind進行預處理 如果ind 0,則ind len a 這樣一來ind就變成了正數下標 預處理之後,當ind 0時,ind 0,相當於頭部插入 當ind len a 時,ind ...