C++中sizeof操作符與strlen函數


  • sizeof操作符:

sizeof是一個操作符,返回一條表達式或一個類型名字所占的字節數。返回值一個常量表達式,類型為size_t。

size_t sizeof(type)

size_t sizeof expr

在sizeof的運算對象中解引用一個無效指針仍然是一種安全的行為,因為指針實際上並沒有被真正使用,sizeof並不需要真的解引用指針也能知道它所指對象的類型。

sizeof對C++的所有內置類型求其所占空間的大小:

環境:win7 64-bits, Code::Blocks 16.01, GUN GCC Compiler with C++11 ISO Standard

Type

Number of bytes

bool

1

char

1

wchar_t

2

char16_t

2

char32_t

4

short

2

int

4

long

4

long long

8

float

4

double

8

long double

12

std::string

4

1. sizeof對數組

傳入數組頭指針,返回每個元素所占的字節數乘以數組的長度。

2. sizeof對C風格字符串

傳入頭指針,返回的是字符串長度加上末尾結束符’\0’的總長度。

C風格字符串有兩種,一種是指針形式:const char* s = “hello”; 將s傳入給sizeof,會認為s為一個指針,返回的是指針所占的字節數。

另一種是數組形式:const char c_str[] = “hello”; 將頭指針c_str傳給sizeof,是按數組形式的計算所占字節數,返回的是字符串長度加上末尾結束符的總長度。

3. sizeof對指針

傳入任意類型的指針,返回值由計算機內存地址總線的寬度決定,32-bits的操作系統返回4,64-bits的操作系統返回8。

4. sizeof對結構體(類)

空的結構體(沒有任何成員),返回1,表示僅含占位符;當要構造一個結構體(類)對象時,首先找出所占字節數最長的數據成員,比如是設為x,然后根據所有成員的所占字節數的總和來計算,所申請的字節數最少n個x就能保存完所有數據,則實際對象所占內存字節數為n*x;並且數據成員儲存的順序是根據在結構體內聲明的順序來儲存的;對於含有虛函數的結構體(類),其額外包括一個成員——指向虛函數表的虛表指針,在32位的機器上,占4個字節,在64位的機器上,占8個字節,同時也會根據其它數據成員補齊。另外,不考慮函數成員所占的內存,函數成員會儲存在代碼區,而不是棧區,所以不考慮。

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

struct A
{
    int a1;
    short a2;
    char a3;
};

struct B
{
    char b1;
    int b2;
    int b3;
    double b4;
};

struct C
{
    char c1;
    virtual void fun() {}
};

int main()
{
    A a;
    cout << sizeof(a) << endl; //輸出8
                               //最長int為4,2*4 >= 4 + 2 + 1
                               //前4個字節儲存a1,緊跟着2個字節儲存a2,再緊跟着1個字節儲存a3
                               //后面還有1個字節為空,什么也不儲存 
    cout << &a.a1 << " " << &a.a2 << " " << &a.a3 << endl;
    B b;
    cout << sizeof(b) << endl; //輸出24 
    C c;
    cout << sizeof(c) << endl; //輸出8 
    
    return 0;
}

 

5. sizeof對聯合體(union)

union在內存中儲存是層疊式的,各成員共享一段內存,因此返回的是所占字節數最長的成員的字節數。例如最長的成員為double,其它無論還有多少個成員且任意小於double的類型,返回的值均為8。

6. sizeof對函數

sizeof對函數操作實際上是求其返回值類型所占的字節數。求值時必須完整地寫出函數調用的形式,但並不實際調用函數。

示例程序

//測試C++中的sizeof() 
#include <iostream>

using std::cout;
using std::cin;
using std::endl;

size_t getPtrSize(char* cptr)
{
    return sizeof(cptr);
}

struct NoMember
{
    
};
struct S_int_char
{
    char c;
    int i;
};
struct S_int_short
{
    short s; //sizeof(short) == 2
    int i;
};
struct S_int_func
{
    int i;
    double ret_i() //不考慮 
    {
        return i;
    }
};
struct S_ONLY_func
{
    double func() 
    {
        return 0;
    }
};

//聯合體 
union my_u  
{  
    int a;  
    float b;  
    double c;  
    char d;  
};  

//函數
short func_short()
{
    return 0;
} 
float func_float(int a, int b)
{
    return 1.1;
}

int main()
{
    //C風格字符串的測試 
    char c_str[] = "Hello!";
    cout << sizeof(char) << " " << sizeof(c_str) <<  " " << getPtrSize(c_str) << endl;
    
    //數組測試
    double d_arr[20];
    cout << sizeof(d_arr) << endl; //返回值為80,4*10 == 80 
    
    //指針的測試
    char* p;
    cout << sizeof(p) << endl; //返回值是4,由計算機內存地址總線的寬度決定
                               //與所指對象無關 
    
    //結構體的sizeof測試 
    NoMember nm;
    cout << sizeof(nm) << endl;
    S_int_char sic;
    cout << sizeof(sic) << endl; //int是4,char是1,
                                 //為了c與i的空間對齊,對c往后相鄰的3個內存加入填充字節
                                 //是空間對齊,則總的空間為i的4加上c的4,得到8
    S_int_short sis;
    cout << sizeof(sis) << endl; //同樣需要內存對齊,返回的也是8 
    S_int_func sif;
    cout << sizeof(sif) << endl; //返回值為4,不考慮成員函數所占的空間 
    S_ONLY_func sof;
    cout << sizeof(sof) << endl; //返回值為1,不考慮成員函數所占的空間 
    
    //聯合體的測試
    my_u u;
    cout << sizeof(u) << endl; //返回值為最大的成員所占空間長度,最大為double,返回8 
    
    //函數的測試
    cout << sizeof(func_short()) << endl;
    cout << sizeof(func_float(1, 2)) << endl;
    
    return 0;
}
  • strlen函數:

strlen函數定義在頭文件cstring.h中,用於計算字符串的長度,但空字符’\0’不計算在內。參數為C風格字符串的頭指針,返回值是字符串的長度,空字符不計算在內。計算原理是順着頭指針向后找,直到遇到空字符才停下來。注意,如果字符數組沒有以空字符結尾,調用strlen()函數可能產生重大錯誤,因為會不斷向前找直到遇到空字符。例如:

char ca[] = {‘a’, ‘b’, ‘c’}; //不以空字符結束
cout << strlen(ca) << endl; //嚴重錯誤

示例程序

#include <iostream>
#include <cstring>
int main()
{
    //騰訊實習軟開 2016-04-03
    const char* s = "hello tencent.\0";
    const char c_str[] = "hello tencent.\0";
    cout << sizeof(s) << " " << strlen(s) << " " << sizeof(c_str) << endl; 
    return 0;
}

測試輸出:

 


免責聲明!

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



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