web-dev-qa-db-ja.com

C ++でconst char *の長さを取得する最良の方法

const char *の長さを取得する2つの方法を知っています。

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の世界では何かを数えるには各ブロックの数を数える必要があり、1回の動きで長さを取得する魔法がないので、最初の方法がconst char *。他の方法私は、最初の方法は多分重い弦には重すぎると思います。とても混乱しています。どちらの方法が良いのか、なぜ他の方法はそうでないのか?

6
JamesAlb

これら2つのメソッドのアセンブリリストを調べてみましょう。

_#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の使用

_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)の方が間違いなく優れています。関数呼び出しは、関数名を通じて意図を示します。ループではできません。


また、多くの場合、Cストリングよりも_std::string_および_std::string_view_の方が適しています。それらを考慮してください。

16
user2486888

この場合、答えはコンパイル時にわかっています。

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()を使用します: :ストリング

1