なぜこれが事実なのか疑問に思うだけです。私は低レベル言語についてもっと知りたいと思っています.Cの基本しか知りません.これはすでに私を混乱させています.
PHP のような言語は、文字列が解釈および/または解析されるときに、文字列を自動的に null で終了しますか?
なぜこれが事実なのか疑問に思うだけです。私は低レベル言語についてもっと知りたいと思っています.Cの基本しか知りません.これはすでに私を混乱させています.
PHP のような言語は、文字列が解釈および/または解析されるときに、文字列を自動的に null で終了しますか?
文字列がCで機能する方法を覚えておいてください。文字列は、一連のバイトとそれに続く値0のヌル文字で構成されます。これには2つの明らかな意味があります。
文字列を移動せずに、文字列がどこで終了するか(つまり、文字列の長さ)を知る方法はありません。最後にあるヌル文字を探します。文字列にゼロを含めることはできません。したがって、JPEG画像のような任意のバイナリブロブをC文字列に格納することはできません。 なぜC文字列がこのように機能するのですか?これは、UNIXとCプログラミング言語が発明されたPDP-7マイクロプロセッサがASCIZ文字列型を持っていたためです。ASCIZは、「末尾にZ(ゼロ)が付いたASCII」を意味します。
これが文字列を保存する唯一の方法ですか?いいえ、実際、これは文字列を格納するための最悪の方法の1つです。重要なプログラム、API、オペレーティングシステム、クラスライブラリの場合、ペストのようなASCIZ文字列は避ける必要があります。
C文字列はcharの配列であり、C配列は、配列の開始位置であるメモリ位置への単なるポインタです。ただし、配列の長さ(または終了)も何らかの方法で表現する必要があります。文字列の場合、ヌル終了が使用されます。もう1つの方法は、文字列の長さをメモリポインタと一緒に運ぶか、長さを最初の配列の場所などに配置することです。それは単なる慣習の問題です。
JavaやPHPなどの高級言語は、サイズ情報を配列とともに自動的かつ透過的に格納するため、ユーザーはそれらについて心配する必要はありません。
メモリとは何かを考えてみてください。任意のビット パターンで満たすことができる、バイト サイズ単位の連続したブロックです。
2a c6 90 f6
文字は、これらのビット パターンの 1 つにすぎません。文字列としての意味は、それをどのように扱うかによって決まります。メモリの同じ部分を見て、整数ビュー (または他の型) を使用すると、異なる値が得られます。
メモリ内の一連の文字の先頭へのポインターである変数がある場合、その文字列がいつ終了し、次のデータ (またはガベージ) が始まるかを知る必要があります。
メモリ内のこの文字列を見てみましょう...
H e l l o , w o r l d ! \0
^
|
+------ Pointer to string
...文字列が文字の後で論理的に終了していることがわかります!
。その文字列が存在しない場合\0
(またはその終了を決定する他の方法がない場合)、メモリをシークするときに、その文字列が終了したことをどのように知ることができますか? 他の言語では、これを解決するために、文字列型とともに文字列の長さが保持されます。
私は、コンピューターに関する基礎知識が限られているときにこの質問をしました。これは、何年も前に役立つ答えでした。それが他の誰かにも役立つことを願っています。:)
C自体には文字列の概念はありません。文字列は、単にchar(またはUnicodeなどの場合はwchar)の配列です。
これらの事実により、Cには「mystring-> length」がないため文字列の長さをチェックする方法がなく、どこかに長さの値が設定されていません。文字列の終わりを見つける唯一の方法は、文字列を繰り返し処理して\0を確認することです。
次のような構造体を使用するCの文字列ライブラリがあります
struct string {
int length;
char *data;
};
\ 0で終了する必要はありませんが、これは標準のCではありません。
C ++、PHP、Perlなどの言語には、独自の内部文字列ライブラリがあり、多くの場合、いくつかの文字列関数を高速化し、\0の必要性を排除する個別の長さフィールドがあります。
他のいくつかの言語(Pascalなど)は、(驚くべきことに)Pascal Stringと呼ばれる文字列型を使用します。これは、文字列の最初のバイトに長さを格納します。これが、これらの文字列が255文字の長さに制限される理由です。
Cでは、文字列は最初の文字へのポインタを介してアクセスされる文字のシーケンスにすぎないためです。
ポインタには長さを格納するスペースがないため、文字列の終わりがどこにあるかを示す必要があります。
Cでは、これはヌル文字で示されることが決定されました。
たとえば、pascalでは、文字列の長さがポインタの直前のバイトに記録されるため、pascal文字列の最大長は255文字です。
これは慣例です。別のアルゴリズム(たとえば、バッファーの先頭の長さ)を使用して実装することもできます。
アセンブラなどの「低レベル」言語では、「NULL」を効率的にテストするのは簡単です。これにより、長さカウンタを追跡するのではなく、NULLで終了する文字列を使用する決定が容易になる場合があります。
それらがどれくらいの長さであるかがわかるように、それらはnullで終了する必要があります。そして、はい、それらは単にcharの配列です。
PHPのような高級言語は、null終端を非表示にするか、まったく使用しないかを選択する場合があります。たとえば、長さを維持する場合があります。オーバーヘッドが関係するため、Cはそのようにはしません。高水準言語は、文字列をcharの配列として実装しない場合もあります。たとえば、文字列をcharの配列のリストとして実装することもできます(一部の言語は実装します)。
C では、文字列はメモリの連続したブロックに割り当てられた文字の配列によって表されるため、ブロックの終わりを示すインジケータ (つまり、ヌル文字)、または長さを格納する方法 (Pascal 文字列のように) が必要です。長さの接頭辞が付いています)。
PHP、Perl、C# などの言語では、文字列は複雑なデータ構造を持つ場合と持たない場合があるため、null 文字があると想定することはできません。不自然な例として、次のような文字列を表す言語を作成できます。
class string
{
int length;
char[] data;
}
ただし、長さフィールドのない通常の文字列としてのみ表示されます。これは、言語のランタイム環境によって計算でき、メモリを正しく割り当ててアクセスするために内部的にのみ使用されるためです。
多くの標準ライブラリ関数がそれらを期待しているため、それらはnullで終了します。