通過程序解讀sizeof

<pre name="code" class="cpp">#include <iostream>
#include <string>

using namespace std;

void foo3(char *c1)
{
    int c3 = sizeof( c1 ); // c3 ==
    cout<< c3 << endl;
}
void foo4(int *c2)
{
    int c4 = sizeof( c2 ); // c4 ==
    cout<< c4 << endl;
}

//字節對齊的細節和編譯器實現相關,但一般而言,滿足三個準則:
//1) 結構體變量的首地址能夠被其最寬基本類型成員的大小所整除;
//2) 結構體每個成員相對於結構體首地址的偏移量(offset)都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充字節;
//3) 結構體的總大小爲結構體最寬基本(內置)類型成員大小的整數倍,如有需要編譯器會在最末一個成員之後加上填充字節.
struct student
{
    int num; // 佔4個字節
    char name[20]; // 佔20個字節
    char sex; // 佔4個字節(結構體爲每個成員分配空間時,根據最寬基本類型成員大小的整數倍進行分配,這裏指的是int/float)
    double age; // 佔4字節
    float score; // 佔4字節
    char addr[30]; // 佔32字節(分配的空間必須爲最寬基本類型成員大小的整數倍)
};

struct S1
{
    char a; // 4字節
    int i; // 4字節
};

// 嵌套的結構體
struct S2
{
    char a; // 4字節
    int i; // 4字節
    student t; // 佔68字節,最寬基本類型成員爲int/float型,4字節(注意,這裏最大成員不是t,因爲它不屬於內置類型;具體計算S2時,student要按S2中的最近倍數來算)
};

// 空結構體
struct S3{};

// 共用體成員共用一個空間,所以其爲最寬基本類型成員的大小
union U
{
    int i;
    char a;
};

int main()
{
    /* 1.
    int count=0; int m=779;
    while(m)
    {
        count++; m=m&(m-1);
    }
    //printf("%d\n",count);
    cout<< count << endl;
    return 0;
    */

    // sizeof的用法
    //(1)數組1
    int p1[10];
    int *p2[10];
    int (*p3)[10];


    cout<< "int p1[10]       sizeof(p1):" << sizeof(p1) << endl;
    cout<< "int *p2[10]      sizeof(p2):" << sizeof(p2) << endl;
    cout<< "int (*p3)[10]    sizeof(p3):" << sizeof(p3) << endl;
    cout<< "----------------------------"<< endl;

    //(2)內置類型
    char a1;
    int a2;
    float a3;
    double a4;
    long a5;
    long double a6;
    string a7;
    string a8="abc"; // string類型變量本質上屬於指針

    cout<< "char:            " << sizeof(a1) << endl;
    cout<< "int:             " << sizeof(a2) << endl;
    cout<< "float:           " << sizeof(a3) << endl;
    cout<< "double:          " << sizeof(a4) << endl;
    cout<< "long:            " << sizeof(a5) << endl;
    cout<< "long double:     " << sizeof(a6) << endl;
    cout<< "string:          " << sizeof(a7) << endl;
    cout<< "string a8=\"abc\": " << sizeof(a8) << endl;
    cout<< "----------------------------"<< endl;


    //(3)指針:所有的指針(包括結構體)均佔4字節(一個int型大小)。
    char *b1;
    int *b2;
    float *b3;
    double *b4;
    long *b5;
    long double *b6;

    cout<< "char*:       " << sizeof(b1) << endl;
    cout<< "int*:        " << sizeof(b2) << endl;
    cout<< "float*:      " << sizeof(b3) << endl;
    cout<< "double*:     " << sizeof(b4) << endl;
    cout<< "long*:       " << sizeof(b5) << endl;
    cout<< "long double*:" << sizeof(b6) << endl;
    cout<< "----------------------------"<< endl;

    //(4)數組2
    char c1[]="abcd";
    int c2[4];

    cout<< "char c1[]=\"abcd\":  " << sizeof(c1) << endl;
    cout<< "int c2[4]:        " << sizeof(c2) << endl;

    //數組名做形參:本質就是指針
    cout<< "foo3(char *c1):   ";
    foo3(c1);
    cout<< "foo3(int *c2):    ";
    foo4(c2);
    cout<< "----------------------------"<< endl;

    // (5)結構體
    S1 s1;
    S1 *s2;
    S2 s3;
    S3 s4;
    student student1;
    student *student2;

    cout<< "S1 s1:             " << sizeof(s1) << endl;
    cout<< "S1 *s2:            " << sizeof(s2) << endl;
    cout<< "student student1:  " << sizeof(student1) << endl;
    cout<< "student *student2: " << sizeof(student2) << endl;
    cout<< "S2 s3:             " << sizeof(s3) << endl;
    cout<< "S3 s4:             " << sizeof(s4) << endl;
    cout<< "----------------------------"<< endl;

    // 共用體
    U u;
    cout<< "U u:               " << sizeof(u) << endl;

	system("pause");

    return 0;
}

<div id="art_demo">本篇文章小編並不是爲大家講解string類型的用法,而是講解我個人比較好奇的問題,就是string 類型佔幾個字節</div><p>在C語言中我們操作字符串肯定用到的是指針或者數組,這樣相對來說對字符串的處理還是比較麻煩的,好在C++中提供了 string 類型的支持,讓我們在處理字符串時方便了許多。</p><p><strong><span style="COLOR: #ff0000">首先,我寫了一段測試代碼,如下所示:
</span></strong></p><pre name="code" class="cpp">#include <iostream>
using namespace std;
int main(void)
{
 string str_test1;
 string str_test2 = "Hello World";
 int value1, value2, value3;
 value1 = sizeof(str_test1);
 value2 = sizeof(str_test2);
 value3 = sizeof(string);
 cout<<"str_test1佔 "<<value1<<" 個字節"<<endl;
 cout<<"str_test2佔 "<<value2<<" 個字節"<<endl;
 cout<<"string佔 "<<value3<<" 個字節"<<endl;
 system("pause");
 return 0;
}
首先,我用G++編譯運行,得到的結果如下圖所示:

結果都是4字節;
<p>這說明string佔4個字節。
之後,我用VS2012編譯運行,得到的結果如下圖所示:
結果都是28字節。</p><p>奇怪,這裏string竟然佔28個字節。
這裏,我們注意觀察,還會發現一個問題,不管有沒有對string類型的變量賦值,或者是賦什麼值,得到的結果是一樣的。</p><p><strong>下面,來解釋上述問題:
</strong>string的實現在各庫中可能有所不同,但是在同一庫中相同一點是,無論你的string裏放多長的字符串,它的sizeof()都是固定的,字符串所佔的空間是從堆中動態分配的,與sizeof()無關。    sizeof(string)=4可能是最典型的實現之一,不過也有sizeof()爲12、32字節的庫實現。通常,我們所用到的 string 類型一般都會是這樣實現:
</p><p><pre name="code" class="cpp">class{      
char *_Ptr;    //指向字符串的指針      
int _Len;      //字符串的長度      
........};



所以,我們一般接觸到的string類型所佔字節數爲 8+。





發佈了25 篇原創文章 · 獲贊 18 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章