2017-06-22 34 views
-3

我知道双向的获得为const char *最好的办法让为const char *的长度在C++中

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

和其他方式的长度很简单

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

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

+5

标准库中的某些东西几乎总是会更快任何你自己编码的东西来做同样的事情,并且肯定不太可能有错误。 –

+1

这两个示例都是等价的,但是由于编译器的具体情况,'strlen'可能会更快,并且无论使用已经为您编写的代码是否更好。 –

+1

为什么你不想使用'strlen()'? – Galik

回答

3

我们来看看这两种方法的汇编清单。

#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; 
} 

使用锵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-串更优选的。考虑他们。

+0

如果你在字符串中加入'\ 0',你会得到相同的编译代码吗?这将是一个错误。 –

+0

@MarkRansom请参阅:https:// godbolt。org/g/mP42o4 –

+0

对于第一种情况,这是一些非常奇怪的代码生成,但我认为它最终会提供正确的答案。 –

-1

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

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(如果指向开始和结尾的指针都可用)或.size()如果处理std :: string

+0

他们明确要求'const char *'作为输入,而你的代码不会与 –

+0

一起工作,我的回答也是针对char *。他的例子也涉及char []类型,但只是通过不使用auto来强制衰减。问题和答案的精神都很明确。 –