配列文字の要素数を知るためにどのような関数を使用できますか?
sizeof()は、使用可能な「スペース」の数を示すため、機能しません。
コメント
回答
strlen
が必要です。
char foo [100] = "bar"; Serial.println (strlen (foo)); // --> prints 3
コメント
- If答えはうまくいきました。" accept "ボタンをクリックしてください(チェックマークのように見えます)。そうすれば、他の人はソリューションは機能しました。
- これを行うには数分待たなければなりませんでした
- これはivid =のデータがのみ機能することに注意してください”4b03894 2c1 “>
にはASCII文字列が含まれており、適切にnullで終了します。さらに、char[]
に長い文字列があり、null終端を追加せずに短い文字列で上書きすると、古い文字列のサイズが取得されます。
回答
ご存知のとおりです。 @NickGammonから回答がありますが、これがどのように機能するかについてもう少し詳細な情報を追加したいと思います。
sizeof()
はワードの通常の意味での関数です。これは、渡すものに割り当てられたメモリのバイト数を与える演算子です。配列を渡すと、配列が使用できるバイト数を返します。配列へのポインタを渡すと、配列のサイズではなく、そのポインタのサイズが返されます。整数変数を渡すと、その整数変数で使用されるバイト数(8ビットの場合は2)が返されます。 AVRのようなシステム、Dueのような32ビットシステムでは4)。
いくつかの例:
char array[50] = "hello"; // sizeof(array) = 50. char *array_p = array; // sizeof(array_p) = 2 or 4 depending on architecture. char single = "a"; // sizeof(single) = 1. char string[] = "hello"; // sizeof(string) = 6 (5 letters plus \0) - it allocates the memory at compile time to fit the string
現在strlen()
。これはsizeof()
とどの程度異なりますか?簡単に言えば、は、C文字列の「NULL」終了文字である文字\0
に到達するまで、文字配列内の文字数をカウントします。前に例を見てみましょうが、代わりにstrlenを使用します。
char array[50] = "hello"; // strlen(array) = 5. char *array_p = array; // strlen(array_p) = 5. char single = "a"; // strlen(single) = ERROR! strlen() doesn"t operate on single characters. char string[] = "hello"; // strlen(string) = 5.
文字列内の文字数は常に最大で返されますが、含まれていません。末尾の\0
文字。
最も単純な形式では、strlen()
関数は次のようになります。
int strlen(const char *data) { int c = 0; const char *p = data; while (*p) { c++; p++; } return c; }
基本的には文字列の最初の文字(*p = data
)から始まり、 “sa \0
かどうか(while (*p)
)、文字数を増やし(c++
)、次の文字に移動します文字列内(p++
)。
プログラム内の文字列を反復処理する場合は、strlen()
最初に文字列の文字数を取得し、次にその値をループで使用します。 strlen()
は最初に文字列を反復処理するため、これは少し無駄です。そのため、最終的に2回文字列を反復処理することになります。 strlen()
関数がポインタ emを使用する方法など、終了文字が見つかるまで文字列内の各文字をステップスルーする最善の方法を学ぶ方がはるかに効率的です。 >メモリ内を移動します。また、文字列の最後に\0
文字が存在することを確認することがいかに重要であるかを確認できます。そうでない場合、strlen()
いつ停止するか知っていますか?文字列の長さがわからないため(sizeof()
は、配列のサイズではなく、渡されたポインタのサイズを返します)、何らかの種類の文字列が必要です。手動マーカーであり、Cの規則では\0
を使用します。
Arduinoのprint()
関数は実際には非常に非効率的に行います。次のようなことを行う場合:
char message[] = "Hello"; Serial.println(message);
実際にはかなり多くの作業を行います。実際には必要ありません。撮影済みステップバイステップ:
- println(message)を呼び出します
- write(message)を呼び出します
- strlen(message)で文字列の長さを取得します
- そしてwrite(message、length)を呼び出します
- 次に0からlength-1にループし、メッセージの各文字を順番にwrite()に送信します。
- 最後に、新しい行の
\r\n
を出力します。
したがって、実際には4関数の深さでネストされて終了し、文字列全体を2回繰り返します。A処理時間を無駄にする方法の典型的な例。write(message)
関数で\0
文字を1回探して文字列を反復処理することにより(ステップ2)、少なくとも2倍の速度で動作します。古き良きArduino …
コメント
- Re「最も単純な形式ではstrlen()関数は次のようになります」、短い(おそらくもっと簡単ですか?)次のような形式になります:
int strlen(const char *data) { const char *p = data; while (*p++); return p-data-1; }
- @ jwpat7 "最も簡単な"、"最短で最もコンパクトな"ではありません。この形式は、小さくて効率的ですが、OP(明らかにプログラマーではない)が理解するのははるかに困難です。
- 同意しました:)また間違いを犯しやすい。また、
\0
がセグメント内の最後のアクセス可能なバイトである場合、*p++
は障害を起こします。ただし、int strlen(const char *data) { const char *p = data; while (*p) ++p; return p-data; }
はその問題を回避します。 - 実際、
*p++
が勝ちました'\0
がセグメント内の最後のアクセス可能なバイトであっても障害が発生します。*p
の部分は最後のバイトにアクセスします。 ++部分は、p
を無効なアドレスに設定します。ただし、その無効なアドレスは'参照されないため、通常のマシンでは障害は発生しません。 - これはコンパイル時のマクロです… 'はマクロではなく、'は演算子(" + "および"-は演算子です)。これらは、プリプロセッサ時に実行されるマクロよりも低レベルです。 sizeof演算子を参照してください。また、 C ++の演算子
回答
use sizeof char nnn[10]; for(int i=0; i< sizeof(nnn)/sizeof(char); i++){ }
コメント
- 質問を正しく読みましたか?
- OPは
sizeof
"は機能しません'私には機能しません"および次に、sizeofを使用することをお勧めします。 - 同じ不明なものを使用する場合は質問に答えられません
char foo [100] = "bar";
-それはどういう意味ですか?答えが必要ですか:3?