簡體   English   中英

在 C++ 中獲取 const char * 長度的最佳方法

[英]Best way to get length of const char * in c++

我知道兩種獲取 const char * 長度的方法

const char * str = "Hello World !";
int Size = 0;
while (str[Size] != '\0') Size++;

其他方式很簡單

const char * str = "Hello World !";
size_t Size = strlen(str);

但我不想使用像strlen這樣的 str lib 函數,而且我認為這個函數也使用我的第一種行為。 因為在 pc 世界中,當我們想要計算某些東西時,我們需要計算每個塊的數量,並且沒有魔法可以通過一次移動來獲得長度,所以我認為第一種方法是獲得const char *長度的最佳選擇。 另一種方式我認為第一種方式對於重弦來說可能太重了。 所以我很困惑。 哪種方式更好,為什么其他方式不是?

讓我們檢查一下這兩種方法的匯編列表。

#include <cstddef>
#include <cstring>

int string_size_1()
{
    const char * str = "Hello World !";
    int Size = 0;
    while (str[Size] != '\0') Size++;
    return Size;
}

int string_size_2()
{
    const char * str = "Hello World !";
    size_t Size = strlen(str);
    return Size;
}

使用帶有標志的 Clang 4.0.0 -std=c++14 -O2

string_size_1():                     # @string_size_1()
        mov     eax, 13
        ret

string_size_2():                     # @string_size_2()
        mov     eax, 13
        ret

鏈接: https : //godbolt.org/g/5S6VSZ

這兩種方法最終都得到完全相同的程序集列表。 此外,編譯器優化了所有內容並只返回一個常量,因為在編譯時字符串文字是已知的。 因此,就性能而言,它們同樣出色。

但在可讀性方面, strlen(str)肯定更好。 函數調用通過函數名稱說明意圖。 循環無法做到這一點。


此外,在許多情況下, std::stringstd::string_view比 C-string 更可取。 考慮他們。

在這種情況下,答案在編譯時已知:

template <std::size_t S>
constexpr std::size_t string_length
(
    char const (&)[S]
)
{
    return S - 1;
}

用法:

std::cout << string_length("example") << std::endl;

對於字符串不是編譯時常量的情況,如果只有指向字符串的指針可用,則使用 strlen,如果指向開頭和結尾的指針都可用,則使用 std::distance ,如果處理 std,則使用 .size() : :細繩

晚了 3 年,但最好遲到永遠。

簡答

#define length(array) ((sizeof(array)) / (sizeof(array[0])))

長答案

所以使用sizeof(array)返回sizeof(array) the size of the type of the array * the amount of elements 知道了這一點,我們就可以做到這一點:

#define length(array) ((sizeof(array)) / (sizeof(array[0])))

你會像這樣使用它:

type yourArray[] = {your, values};
length(yourArray);    // returns length of yourArray

例如:

#include <stdlib.h>
#include <stdio.h>

#define length(array) ((sizeof(array)) / (sizeof(array[0])))


int main()
{
    const char *myStrings[] = {"Foo", "Bar", "Hello, World!"};    // 3 elements
    int myNums[] = {0, 1, 5, 7, 11037};    // 5 elements
    char myChars[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};    // 7 elements

    printf("Length of myStrings array: %lu\n", length(myStrings));
    printf("Length of myNums array: %lu\n", length(myNums));
    printf("Length of myChars array: %lu\n", length(myChars));

    return 0;

    /* Output:
           Length of myStrings array: 3
           Length of myNums array: 5
           Length of myChars array: 7 */
}

我測試了它,它也適用於未初始化的數組,可能是因為它們包含來自相同類型的垃圾(未初始化)。 整數未初始化數組包含隨機整數,而 const char* 未初始化數組包含 (null),它被視為 const char*。

現在,這只適用於堆棧上的數組。 指向用作數組的堆中保留空間的指針會產生意想不到的結果。 例如:

int *myNums = (int *)malloc(3 * sizeof(int));    // Space for 3 integers
printf("Length of myNums: %lu\n");  // Outputs 2 instead of 3

所以被勸告。 無論如何,誰在堆上使用數組。

注意:這與此問題有關,因為它根據要求與 const char * 一起使用。 也適用於其他類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM