C語言 sizeof()用法介紹


本文 轉自https://www.cnblogs.com/huolong-blog/p/7587711.html

 

1.      定義

sizeof是一個操作符(operator)。

其作用是返回一個對象或類型所占的內存字節數。

 

2.      語法

sizeof有三種語法形式:

1)  sizeof (object);  //sizeof (對象)

2)  sizeof object;   //sizeof 對象

3)  sizeof (type_name);  //sizeof (類型)

對象可以是各種類型的變量,以及表達式(一般sizeof不會對表達式進行計算)。

sizeof對對象求內存大小,最終都是轉換為對對象的數據類型進行求值。

sizeof (表達式); //值為表達式的最終結果的數據類型的大小

 

舉例:

復制代碼
int i;  
sizeof(int); //值為4  
sizeof(i); //值為4,等價於sizeof(int)  
sizeof i; //值為4  
sizeof(2); //值為4,等價於sizeof(int),因為2的類型為int  
sizeof(2 + 3.14); //值為8,等價於sizeof(double),因為此表達式的結果的類型為double  

char ary[sizeof(int) * 10]; //OK,編譯無誤
復制代碼

 

 

1.      基本數據類型的sizeof

這里的基本數據類型是指short、int、long、float、double這樣的簡單內置數據類型。

由於它們的內存大小是和系統相關的,所以在不同的系統下取值可能不同。

 

2.      結構體的sizeof

結構體的sizeof涉及到字節對齊問題。

為什么需要字節對齊?計算機組成原理教導我們這樣有助於加快計算機的取數速度,否則就得多花指令周期了。為此,編譯器默認會對結構體進行處理(實際上其它地方的數據變量也是如此),讓寬度為2的基本數據類型(short等)都位於能被2整除的地址上,讓寬度為4的基本數據類型(int等)都位於能被4整除的地址上,依次類推。這樣,兩個數中間就可能需要加入填充字節,所以整個結構體的sizeof值就增長了。

字節對齊的細節和編譯器的實現相關,但一般而言,滿足三個准則:

1)  結構體變量的首地址能夠被其最寬基本類型成員的大小所整除。

2)  結構體的每個成員相對於結構體首地址的偏移量(offset)都是成員大小的整數倍,如有需要,編譯器會在成員之間加上填充字節(internal adding)。

3)  結構體的總大小為結構體最寬基本類型成員大小的整數倍,如有需要,編譯器會在最末一個成員后加上填充字節(trailing padding)。

 

    注意:空結構體(不含數據成員)的sizeof值為1。試想一個“不占空間“的變量如何被取地址、兩個不同的“空結構體”變量又如何得以區分呢,於是,“空結構體”變量也得被存儲,這樣編譯器也就只能為其分配一個字節的空間用於占位了。

 

例子:

  1. 復制代碼
    struct S1  
    {  
        char a;  
        int b;  
    };  
    sizeof(S1); //值為8,字節對齊,在char之后會填充3個字節。  
      
    struct S2  
    {  
        int b;  
        char a;  
    };  
    sizeof(S2); //值為8,字節對齊,在char之后會填充3個字節。  
      
    struct S3  
    {  
    };  
    sizeof(S3); //值為1,空結構體也占內存
    復制代碼

3.      聯合體的sizeof

結構體在內存組織上市順序式的,聯合體則是重疊式,各成員共享一段內存;所以整個聯合體的sizeof也就是每個成員sizeof的最大值。

 

例子:

  1. 復制代碼
    union u  
    {  
        int a;  
        float b;  
        double c;  
        char d;  
    };  
      
    sizeof(u); //值為8  
    復制代碼

     

4.      數組的sizeof

數組的sizeof值等於數組所占用的內存字節數。

注意:1)當字符數組表示字符串時,其sizeof值將’/0’計算進去。

            2)當數組為形參時,其sizeof值相當於指針的sizeof值。 

例子1:

  1. char a[10];  
    char n[] = "abc";   
      
    cout<<"char a[10]                 "<<sizeof(a)<<endl;//數組,值為10  
      
    cout<<"char n[] = /"abc/"           "<<sizeof(n)<<endl;//字符串數組,將'/0'計算進去,值為4

 例子2:

  1. 復制代碼
    void func(char a[3])  
    {  
        int c = sizeof(a); //c = 4,因為這里a不在是數組類型,而是指針,相當於char *a。  
    }  
      
    void funcN(char b[])  
    {  
        int cN = sizeof(b); //cN = 4,理由同上。  
    } 
    復制代碼

5.      指針的sizeof

指針是用來記錄另一個對象的地址,所以指針的內存大小當然就等於計算機內部地址總線的寬度。

在32位計算機中,一個指針變量的返回值必定是4。

指針變量的sizeof值與指針所指的對象沒有任何關系。

  例子:

  1. 復制代碼
    char *b = "helloworld";  
    char *c[10];  
    double *d;  
    int **e;  
    void (*pf)();    
      
    cout<<"char *b = /"helloworld/"     "<<sizeof(b)<<endl;//指針指向字符串,值為4  
    cout<<"char *b                    "<<sizeof(*b)<<endl; //指針指向字符,值為1  
    cout<<"double *d                  "<<sizeof(d)<<endl;//指針,值為4  
    cout<<"double *d                  "<<sizeof(*d)<<endl;//指針指向浮點數,值為8  
    cout<<"int **e                  "<<sizeof(e)<<endl;//指針指向指針,值為4  
    cout<<"char *c[10]                "<<sizeof(c)<<endl;//指針數組,值為40  
    cout<<"void (*pf)();              "<<sizeof(pf)<<endl;//函數指針,值為4  
    復制代碼

     

6.      函數的sizeof

sizeof也可對一個函數調用求值,其結果是函數返回值類型的大小,函數並不會被調用。

對函數求值的形式:sizeof(函數名(實參表))

注意:1)不可以對返回值類型為空的函數求值。 

            2)不可以對函數名求值。

           3)對有參數的函數,在用sizeof時,須寫上實參表。

 例子:

  1. 復制代碼
    #include <iostream>  
    using namespace std;  
      
    float FuncP(int a, float b)  
    {  
        return a + b;  
    }  
      
    int FuncNP()  
    {  
        return 3;  
    }  
      
    void Func()  
    {  
    }  
      
    int main()  
    {  
    cout<<sizeof(FuncP(3, 0.4))<<endl; //OK,值為4,sizeof(FuncP(3,0.4))相當於sizeof(float)  
    cout<<sizeof(FuncNP())<<endl; //OK,值為4,sizeof(FuncNP())相當於sizeof(int)  
    /*cout<<sizeof(Func())<<endl; //error,sizeof不能對返回值為空類型的函數求值*/  
    /*cout<<sizeof(FuncNP)<<endl; //error,sizeof不能對函數名求值*/  
    return 0;  
    }  
    復制代碼

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM