牛逼的sizeof

sizeof是什麼?爲什麼他會牛逼?我們一起來看看。
       sizeof
C/C++中的一個操作符(operator),簡單的說其作用就是返回一個對象或者類型所佔的內存字節數。——摘自百度百科。 這樣一來,不管是你對某個類型不清楚其所佔內存情況,還是有人故意要用一個很複雜的變量定義來爲難你,都可以藉助sizeof輕鬆解決,這是一方面;另一方面如果是應聘C/C++,這個sizeof出現的頻率還是相當高的,並且常常和指針,數組聯繫起來,現場面試估計會被整的夠嗆。因此,有必要重點分析一下。
    1.sizeof(int/double/char/float/long),這是最基礎的一組,對應的值都在註釋裏有,有疑問可以自行運行代碼。需要注意的是char在任意系統下都佔一個字節(在java中佔2個字節),而其他的類型由所使用的編譯器決定,看看代碼(我所使用的是32位編譯器):   
 
#include <stdio.h>
int main(){
    
    int a = 2;
    double b = 3.0;
    char c = 'a';
    float d = 4.0;
    long e = 0;
    
 
    printf("sizeof(a)=%d\n", sizeof(a));//int is 4
    printf("sizeof(b)=%d\n", sizeof(b)); //double is 8
    printf("sizeof(c)=%d\n", sizeof(c)); //char is 1
    printf("sizeof(d)=%d\n", sizeof(d)); //float is 4
    printf("sizeof(e)=%d\n", sizeof(e)); //long is 4
    return 0;
}
 
 2.sizeof(各種類型的指針),不管是int,double, short, char, float。結果統統是4。怎麼樣?有沒有很詭異,爲啥?他到底是爲啥?來,上段代碼再說(接上面代碼):
 int *qa = &a;
    double *qb = &b;
    char *qc = &c;
    float *qd = &d;
    long *qe = &e;
    
    printf("sizeof(qa)=%d\n", sizeof(qa));//int * is 4
    printf("sizeof(qb)=%d\n", sizeof(qb)); //double *  is 4
    printf("sizeof(qc)=%d\n", sizeof(qc)); //char *  is 4
    printf("sizeof(qd)=%d\n", sizeof(qd)); //float *  is 4
    printf("sizeof(qe)=%d\n", sizeof(qe)); //long *  is 4

 
    return 0;
其實,“指針是一個無符號整數(unsigned int),它是一個以當前系統尋址範圍爲取值範圍的整數。32位系統下尋址能力(地址空間)是4G Bytes(0~2^32-1)二進制表示長度爲32bits(也就是4Bytes)。”--摘自百度百科。
那麼,不管是何種類型的指針,他都只是指針類型,不要被迷惑了。
3.sizeof與一維數組
sizeof其數組名,先上代碼再分析:
    int a[2];
    double b[2];
    
    printf("sizeof(a)=%d\n", sizeof(a)); //int a[2]  is 8
    printf("sizeof(b)=%d\n", sizeof(b)); // double b[2] is16
看到了嗎?int型的其結果是8,即sizeof(int)*2=4*2=8;double其結果是16,即sizeof(double)*2=8*2=16;很清楚了吧,每種類型的一維數組,sizeof其數組名,結果是 (對應數組類型所佔位數) * (數組元素的個數)。
另外一種情況,當數組作爲參數傳遞時,得到的結果是4,因爲此時他退化爲指針類型。
4.sizeof與二維數組,sizeof其數組名,先上代碼:
    int p[3][2];
    
    printf("sizeof(p)=%d\n", sizeof(p)); // p[3][2] is 24
其結果與一維數組相似,計算方法:4 *(3 * 2)=24,理解吧! 
5.sizeof、二維數組、指針,有點繞,做好心理準備: 
int *(*p)[3][2];
    int **p1[3][2];
    
    printf("sizeof(p)=%d\n", sizeof(p)); // p is 4
    printf("sizeof(*p)=%d\n", sizeof(*p)); // *p is 24
    printf("sizeof(**p)=%d\n", sizeof(**p)); // **p is 8
    printf("sizeof(p1)=%d\n", sizeof(p1)); // p1 is 24
    printf("sizeof(*p1)=%d\n", sizeof(*p1)); // *p is 8
    printf("sizeof(**p1)=%d\n", sizeof(**p1)); // **p is 4 
是不是有點暈,我們一行一行分析:
在分析前先簡單說說指針的定義與取指針所指元素,在定義行‘*’只是一個指針的代號而已,標明p爲指針;而在使用時‘*’是取指針所指元素的操作。好,下面來看每一行的分析:
第一種情況:*(*p)[3][2]
1)p在定義的時候先(*p)也就是說p是一個指針型,那麼結果爲4
2)*p,既然p是一個指針,那麼*p就是取指針元素的值了,後面有(*p)[3][2],所以他指得就是指針型的二維數組,*p就是他的數組名了。那麼取他的元素就是4*(3*2)=24了;可能有點亂。
3)**p,上面說*p是一個數組,注意:*p即代表數組名,也代表數組的第一個元素指針(地址),那麼這次就是取數組的第一個元素了,而二維數組又可以看作存儲一維數組的一位
,有點亂嗎?在讀一邊 ,二維數組可看作存儲一維數組的一數組,此時第一個元素是一個一維數組,所以結果就是4*2=8;
第二種情況:**p[3][2] 
1)p在定義的時候直接與p[3][2]相連接,那麼p就是一個二維數組的數組名,根據上面討論的第4條,結果爲4*(3*2)=24.
2)*p,既然p是一個數組名,根據第一種情況的第3)條中所說,數組名
也代表數組的第一個元素指針(地址)那麼*p就是取數組第一個元素的值了,而第一個元素是一個一維數組,所以*p也是二維數組內部第一個一維數組的數組名,那麼計算結果爲4*2=8;
3)**p,上面說*p
是二維數組內部第一個一維數組的數組名,那麼**p就是取第一個數組的第一個元素,此元素是int型,計算結果就是4了;
其他情況也大同小異,主要注意下面這兩句話:
·1 二維數組又可以看作存儲一維數組的一位數組;
·2 
數組名也代表數組的第一個元素指針(地址); 
好的,這篇文章到此也就結束了,歡迎討論,下篇再見。
發佈了47 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章