首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在c++中获取const char *长度的最佳方法

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

Stack Overflow用户
提问于 2017-06-22 12:21:16
回答 3查看 46.8K关注 0票数 16

我知道两种获取常量字符长度的方法*

代码语言:javascript
复制
const char * str = "Hello World !";
int Size = 0;
while (str[Size] != '\0') Size++;

另一种方法很简单

代码语言:javascript
复制
const char * str = "Hello World !";
size_t Size = strlen(str);

但是我不想使用像strlen这样的str lib函数,我认为这个函数也使用了我的第一种方式行为。因为在pc世界中,当我们想要计算一些东西时,我们需要计算每个块的长度,并且没有魔法可以通过一个动作来获得长度,所以我认为第一种方法是获得const char *长度的最佳选择。另外,我认为第一种方法可能对重的弦来说太重了,所以我很困惑。哪种方法更好,为什么其他方法不好?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-06-22 12:38:59

让我们检查一下这两个方法的汇编清单。

代码语言:javascript
复制
#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;
}

使用带有标志-std=c++14 -O2的Clang 4.0.0

代码语言:javascript
复制
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更可取。考虑一下它们。

票数 32
EN

Stack Overflow用户

发布于 2017-06-22 12:54:35

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

代码语言:javascript
复制
template <std::size_t S>
constexpr std::size_t string_length
(
    char const (&)[S]
)
{
    return S - 1;
}

用法:

代码语言:javascript
复制
std::cout << string_length("example") << std::endl;

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

票数 2
EN

Stack Overflow用户

发布于 2021-04-06 23:23:26

晚了3年,但迟了总比不到好。

简短的回答

代码语言:javascript
复制
#define length(array) ((sizeof(array)) / (sizeof(array[0])))

长长的答案

所以使用sizeof(array)会返回the size of the type of the array * the amount of elements。了解了这一点,我们可以实现以下目标:

代码语言:javascript
复制
#define length(array) ((sizeof(array)) / (sizeof(array[0])))

您可以像这样使用它:

代码语言:javascript
复制
type yourArray[] = {your, values};
length(yourArray);    // returns length of yourArray

例如:

代码语言:javascript
复制
#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 */
}

我测试了它,它也适用于未初始化的数组,可能是因为它们包含来自同一类型的垃圾(来自未初始化)。整数未初始化数组包含随机整数,且常量char*未初始化数组包含(null),它被视为常量char*。

现在,这只适用于堆栈上的数组。指向用作数组的堆中保留的空间的指针将产生意外的结果。例如:

代码语言:javascript
复制
int *myNums = (int *)malloc(3 * sizeof(int));    // Space for 3 integers
printf("Length of myNums: %lu\n", length(myNums));  // Outputs 2 instead of 3

因此,请注意。不管怎样,谁在堆上使用数组呢?

注意:这与这个问题相关,因为它可以根据请求与const char *一起使用。也可以与其他类型一起使用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44690087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档