特定の状況で、文字の配列(もちろんnull文字で終わる)があり、その直後にメモリの次の位置に0
符号なしintとして格納する場合、コンピューターはこれらをどのように区別しますか二?
pic X occurs m to n depending on v
(カウントは直前だけでなくどこでも可能ですが、保存はより複雑です。
特定の状況で、文字の配列(もちろんnull文字で終わる)があり、その直後にメモリの次の位置に0
符号なしintとして格納する場合、コンピューターはこれらをどのように区別しますか二?
pic X occurs m to n depending on v
(カウントは直前だけでなくどこでも可能ですが、保存はより複雑です。
回答:
そうではありません。
文字列ターミネータは、すべて0ビットを含むバイトです。
unsigned intは2バイトまたは4バイト(環境に応じて)で、それぞれにすべて0ビットが含まれます。
2つのアイテムは異なるアドレスに保存されます。コンパイルされたコードは、前者の文字列に適した操作を実行し、後者の場所に符号なし2進数に適した操作を実行します。(コードにバグがあるか、または危険なほど巧妙なコードがない限り!)
ただし、これらのバイトはすべてCPUから見ると同じように見えます。メモリ内のデータ(現在最も一般的な命令セットアーキテクチャ)は、それに関連付けられた型を持ちません。これは、ソースコードにのみ存在する抽象化であり、コンパイラにとってのみ何かを意味します。
編集追加:例:文字列を構成するバイトに対して算術演算を実行することは完全に可能であり、一般的です。8ビットASCII文字のストリングがある場合、32(10進数)を加算または減算することにより、ストリング内の文字を大文字と小文字の間で変換できます。または、別の文字コードに変換する場合は、その値を、他のコードで同等のビットコーディングを提供する要素を持つ配列へのインデックスとして使用できます。
CPUにとって、文字は実際には非常に短い整数です。(16、32、または64ではなく、それぞれ8ビット。)人間にとって、それらの値はたまたま読み取り可能な文字に関連付けられていますが、CPUはそれを認識していません。また、「ヌルバイトが文字列を終了する」という「C」規約についても何も知りません(他の回答やコメントで指摘されているように、その規約がまったく使用されないプログラミング環境もあります) 。
確かに、x86 / x64には文字列(REPプレフィックスなど)で頻繁に使用される傾向があるいくつかの命令がありますが、希望する結果が得られれば、整数の配列でも同様に使用できます。
つまり、違いはありません(ただし、intの幅は2または4バイトで、charの幅は1だけです)。
問題は、すべての最新のライブラリがヌルターミネータ技術を使用するか、文字列の長さを保存することです。そして、どちらの場合でも、プログラム/コンピューターは、ヌル文字を読み取るか、サイズが示す数の文字を読み取ったときに、文字列の終わりに到達したことを認識します。
この問題は、nullターミネーターが欠落しているか、プログラムが想定外のメモリーから読み取りを開始するために長さが間違っている場合に発生します。
違いはありません。マシンコード(アセンブラー)には変数タイプはありませんが、代わりにデータのタイプは命令によって決定されます。
より良い例はでint
ありfloat
、メモリに4バイトがある場合、int
それがaかa float
(または他の何か)の情報はありませんが、整数加算と浮動小数点加算には2つの異なる命令があります。命令はデータに対して使用され、それは整数であり、その逆も同様です。
文字列についても同様です。たとえば、アドレスを調べてバイトに達するまでバイトをカウントするコードがある場合、\0
文字列の長さを計算する関数と考えることができます。
もちろん、このようなプログラミングは完全に狂気になります。そのため、マシンコードにコンパイルされ、アセンブラーでプログラムをほとんど実行しない高レベル言語があります。
科学的な一言で言うと、メタデータです。
メタデータは、特定の場所にあるデータがint、文字列、プログラムコードなどであるかどうかをコンピューターに伝えます。このメタデータは、プログラムコード(Jamie Hanrahanが述べたように)の一部であるか、どこかに明示的に保存できます。
最近のCPUは、多くの場合、プログラムコードに割り当てられたメモリ領域とデータ領域を区別できます(たとえば、NXビットhttps://en.wikipedia.org/wiki/NX_bit)。エキゾチックなハードウェアの中には、文字列と数字を区別できるものもあります、はい。ただし、通常のケースでは、ソフトウェアがこの問題を処理します。暗黙のメタデータ(コード内)または明示的なメタデータ(オブジェクト指向VMは、データ(オブジェクト)の一部としてメタデータ(タイプ/クラス情報)を保存することがよくあります) 。
異なる種類のデータを区別しないことの利点は、一部の操作が非常に単純になることです。I / Oサブシステムは、ディスクから読み取りまたはディスクに書き込むデータが実際にプログラムコード、人間が読めるテキストまたは数値であるかどうかを必ずしも知る必要はありません。機械を通して運ばれるのは、ほんの少しだけです。プログラムコードで派手なタイピングの問題に対処しましょう。
そうではありません。あなたはそれを行う!
または、コンパイラ/インタープリター。
指示がコンピュータに0
数字として追加するように指示した場合、それが実行されます。に到達した後にデータの印刷を停止するようにコンピューターに指示した場合0
、「\0'
char 」として実行されます。
言語には、データの処理方法を保証するメカニズムがあります。Cでは変数は種類、等を有していてint
、float
そしてchar
、コンパイラは、各データ型に右の命令を生成します。しかし、Cを使用すると、変数から別のタイプの別の変数にデータをキャストできます。へのポインターも数値として使用できます。コンピューターにとっては、他のすべてのビットと同じです。