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 *
。他の方法私は、最初の方法は多分重い弦には重すぎると思います。とても混乱しています。どちらの方法が良いのか、なぜ他の方法はそうでないのか?
これら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
_の方が適しています。それらを考慮してください。
この場合、答えはコンパイル時にわかっています。
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()を使用します: :ストリング