C言語: 数値の0
,NULL
,空文字('\0'
),空文字列(""
)の違い
C/C++の数値の0
,NULL
,空文字('\0'
),空文字列(""
)の違いがよくわからなくなったので整理する。
内部的な値
まず,これらの内部的な値を以下のプログラムで確認する。
上記プログラムをUbuntu 16.04でgcc 5.4.0でコンパイルして実行すると以下の結果が出力される(コンパイラーが警告を出すが今回は無視)。
この結果を踏まえて,それぞれの意味を整理する。
項目 | 説明 |
---|---|
0 | 整数の0。 |
NULL | どこも参照していないことを表すポインター(マクロ)。値はアドレスの0番(値0)。 |
空文字('\0' ) | ASCIIコード(文字コード)値0(NULL文字)を指す。 |
空文字列("" ) | 文字'\0' の配列(文字配列)。値はこの配列の先頭アドレスとなる。 |
整数の0
,NULL
,空文字('\0'
)は値がともに0であるため,結果としては混同して使っても問題ないことが多い。
ただし,空文字列は大きく意味が異なる。空文字列は空文字('\0'
)を要素として持つ要素数1の配列である。そのため,単独の空文字列の値は配列の先頭アドレスとなる。空文字列の先頭要素[0]は空文字('\0'
)であるため値は0である。
間違いの例
例えば,引数に文字列を受け取り,受け取った文字列を1文字ずつ処理することを考える。このときに,文字列を1個ずつループするために,以下のようなループで処理する。
ここでは,文字列の終端のNULL文字('\0'
)に到達することをループの終了条件に指定している。
しかし,このPrintChars.cをコンパイルして実行すると無限ループが発生する。理由は6行目のfor文の評価式(pIn
)をポインター(文字配列)のまま評価してしまっているからだ。この場合,アドレスとしてNULL文字の位置まで到達しても,アドレスのまま評価してしまっているため,終了しなくなってしまっている。
正しくは,5行目のコメントに書いてあるように,評価式に関節参照演算子*
を使用して,文字配列のアドレスではなく,文字配列の要素を参照(*pIn
)する。こうすることで,文字列の終端に到達したときは空文字('\0'
)が評価され,期待通りに以下の結果が得られる。
まとめ
おそらく,C/C++の中では初歩的なことだとは思うが,自分の中で理解が不十分であり,ネット上にわかりやすい情報がなかったので整理した。次回からは同じような間違いや勘違いは減るだろう。
nullと””、\0とEOFの違いについて。 -いつも気になっていたのですが、(- C言語・C++・C# | 教えて!goo