在c ++中获取const char *长度的最佳方法

时间:2017-06-22 04:21:16

标签: c++ string-length strlen

我知道两种方法来获得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 *长度的最佳选择。换句话说,我认为第一种方式对于重型弦乐来说可能太重了。所以我很困惑。哪种方式更好,为什么其他方式不是?

3 个答案:

答案 0 :(得分:11)

让我们检查这两种方法的汇编列表。

#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字符串更优选。考虑一下。

答案 1 :(得分:1)

晚了 3 年,但晚了总比没有好。

简答

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

长答案

因此使用 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 * 一起使用。也适用于其他类型。

答案 2 :(得分:0)

在这种情况下,答案在编译时是已知的:

array.reduce((a, e) => compare(a, e) < 0 ? a : e)

用法:

    $sql = "select *from table where email ='".$email."'";
            $query = $db->prepare($sql);
            $user_array = $query ->execute();

    if(count($user_array) > 0){
       //You can use insert query here 
    }else{
       //email already exist.
    }

对于字符串不是编译时常量的情况,如果只有指向字符串的指针可用,则使用strlen;如果指向开头和结尾的指针都可用,则使用std :: distance;如果处理,则使用.size()一个std :: string