C++ 中字串的 sizeof 運算子和 strlen 函式的區別

Jinku Hu 2023年1月30日 2021年10月2日
  1. sizeof 運算子特徵和使用場景
  2. 使用 std::string::size 成員函式檢索字串中的字元數
C++ 中字串的 sizeof 運算子和 strlen 函式的區別

本文將演示在 C++ 中使用 sizeof 運算子而不是 strlen 函式處理字串時的多個差異。

sizeof 運算子特徵和使用場景

sizeof 運算子是一個一元運算子,用於檢索給定表示式或資料型別的儲存大小。此運算子以位元組為單位評估物件大小,並且 sizeof(char) 保證為 1

有一種誤解,認為 1 位元組總是等於 8 位,因此,我們可以以位為單位計算物件的大小。實際上,語言本身並不能保證一個位元組是 8 位。它主要取決於底層硬體平臺。儘管如此,大多數當代通用硬體仍使用 8 位位元組。

請注意,sizeof 運算子不能應用於包含函式或不完整型別或位域的表示式。在以下示例程式碼中,我們將 sizeof 運算子應用於兩個不同型別的陣列,結果在你的平臺上也可能相同。由於 char 保證有 1 個位元組的大小,20 個字元的陣列將佔用 20 個位元組。

另一方面,long long 資料型別是實現定義的,在這種情況下,它恰好是 8 個位元組。因此,總陣列大小為 160 位元組。請注意,我們還可以通過將 sizeof 整個陣列除以 sizeof 一個元素來找到陣列中的元素數,如下一個示例的最後幾行所示。

#include <iostream>

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

int main(){
    char arr[20];
    long long arr2[20];

    cout << "sizeof ( array of 20 long longs ) : " << sizeof arr << endl;
    cout << "sizeof ( array of 20 long longs ) : " << sizeof arr2 << endl;
    cout << "length of array of 20 chars)      : " << ((sizeof arr) / (sizeof arr[0])) << endl;
    cout << "length of array of 20 long longs ): " << ((sizeof arr2) / (sizeof arr2[0])) << endl;

    return EXIT_SUCCESS;
}

輸出:

sizeof ( array of 20 long longs ) : 20
sizeof ( array of 20 long longs ) : 160
length of array of 20 chars)      : 20
length of array of 20 long longs ): 20

使用 sizeof 運算子來查詢字串的長度是錯誤的。讓我們考慮 C++ 中字串的兩種表示型別,一個字串和一個 std::string 類。前一個主要使用 char 指標訪問,在其上應用 sizeof 將檢索指標本身的儲存大小,而不是整個字串。

如果我們嘗試使用 sizeof 運算子檢索 std::string 物件的大小,我們將獲得物件的儲存大小,這將不是字串中的字元數,如下面的程式碼片段所示。

#include <iostream>
#include <string>
#include <cstring>

using std::cout;
using std::endl;
using std::string;

int main(){
    const char *text1 = "arbitrary string value 1";
    string text2 = "arbitrary string value 2";

    cout << "sizeof char* : " << sizeof text1 << endl;
    cout << "sizeof string: " << sizeof text2 << endl;
    cout << "sizeof string.data: " << sizeof text2.data() << endl;

    return EXIT_SUCCESS;
}

輸出:

sizeof char* : 8
sizeof string: 32
sizeof string.data: 8

然後我們得到了 strlen 函式,它是 C 字串庫的殘餘。它計算給定字串的長度,函式返回位元組數作為整數值。strlen 可以應用於儲存有效字串的 char 指標或 std::string::c_str 返回的值,但它不應該是 C++ 程式設計師的選擇。

#include <iostream>
#include <string>
#include <cstring>

using std::cout;
using std::endl;
using std::string;

int main(){
    const char *text1 = "arbitrary string value 1";
    string text2 = "arbitrary string value 2";

    cout << "strlen char* : " << strlen(text1) << endl;
    cout << "strlen string: " << strlen(text2.c_str()) << endl;

    return EXIT_SUCCESS;
}

輸出:

strlen char* : 24
strlen string: 24

使用 std::string::size 成員函式檢索字串中的字元數

相反,C++ 程式設計師應該利用 std::string 類的 size 成員函式,因為它提供了一種更安全的處理字串的方法。請注意,如果我們有一個字串,我們甚至可以使用 size 成員函式。我們需要構造一個新的 string 物件並直接對返回值呼叫 size 函式。以下程式碼示例顯示了這兩種方案的主要用途。

#include <iostream>
#include <string>
#include <cstring>

using std::cout;
using std::endl;
using std::string;

int main(){
    const char *text1 = "arbitrary string value 1";
    string text2 = "arbitrary string value 2";

    cout << "length char* : " << string(text1).size() << endl;
    cout << "length string: " << text2.size() << endl;

    return EXIT_SUCCESS;
}

輸出:

length char* : 24
length string: 24
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相關文章 - C++ String