C言語関係掲示板

過去ログ

No.905 NULL文字の意味

[戻る] [ホームページ]
No.675

NULL文字の意味がいまいち分かりません。
投稿者---ソウスケ(2003/11/16 20:44:12)


題名の通りNULL文字の意味がよく分かりません。
僕が始めに思っていたNULL文字の意味は「機械が「文字の羅列」を「文字列」と認識するために語尾にNULL文字をいれてる」って言う考えでした。
↓のソースを実行させると「HELLO」と表示されますよね、しかし語尾にNULL文字ははいっていないですよね。なぜ表示されるんでしょうか?
なくてもいけるんだとしたらNULL文字の必要性って何なんでしょうか?

#include <stdio.h>

int main(void)
{
	char str1[5] = {'H','E','L','L','O'};
	char str2[5] = "HELLO";              
	
	printf("%s\n%s",str1,str2);
	
	return(0);
}


No.677

Re:NULL文字の意味がいまいち分かりません。
投稿者---落ち武者(2003/11/16 22:49:57)


う〜ん、今打家のコンパイラ(VC6.0++)でやってみたら、ちゃんと表示されませんでした。
考えられる理由としては、str1のほうは、たまたま後ろがNULL文字または、スペースになってただけ。(家の方では、変な文字がいっぱいでました。)str2のほうは、"HELLO"と、ダブルコーテーションでかこんで宣言した時点で、最後にNULL文字がつくことは、暗黙に了解されているので、きちんと出たのだと思います。ちなみに、家のコンパイラでは、"HELLO"は6文字になるので、文字数が足りないとゆうエラーがでました。
実行環境などによって、実行結果に違いが出るとは思いますが、文字列の場合、必ず最後にNULLはいります。いろいろと、ためしてみてください。


No.679

Re:NULL文字の意味がいまいち分かりません。
投稿者---ソウスケ(2003/11/17 00:25:35)


VCではいけませんでしたか?なぜでしょうね。。。Borlnd C++ だったら何回やっても表示されます。

>str2のほうは、"HELLO"と、ダブルコーテーションでかこんで宣言した時点で、最後にNULL文字がつくことは、暗黙に了解されているので、きちんと出たのだと思います。ちなみに、家のコンパイラでは、"HELLO"は6文字になるので、文字数が足りないとゆうエラーがでました。

暗黙の了解だと言っても配列は5個しかないんだからエラーになると思うんですが・・・、だからたぶん家でやったほうが正解だと思います。

コンパイラによってここまでちがうのかな・・・。


No.681

Re:NULL文字の意味がいまいち分かりません。
投稿者---YuO(2003/11/17 05:07:41)


> str2のほうは、"HELLO"と、ダブルコーテーションでかこんで宣言した時点で、最後にNULL文字がつくことは、暗黙に了解されているので、きちんと出たのだと思います。
> ちなみに、家のコンパイラでは、"HELLO"は6文字になるので、文字数が足りないとゆうエラーがでました。

ちゃんとC言語としてコンパイルしましたか?

char ch[5] = "HELLO";
はC言語としては正しいですが,C++言語としては間違いです。

C言語の場合,これは,
char ch[5] = { 'H', 'E', 'L', 'L', 'O' };
として扱われます。
#末尾にナル文字は付加されません。


No.687

Re:NULL文字の意味がいまいち分かりません。
投稿者---ソウスケ(2003/11/17 18:43:45)


一方ではNULL文字が付かなかったら関数の動作は未定義と言っていますよね、それでもう一方では、C言語では正しいと言っていますが、あまり意味が分からないんですけどどういうことでしょう?

No.688

Re:NULL文字の意味がいまいち分かりません。
投稿者---YuO(2003/11/17 19:14:38)


>一方ではNULL文字が付かなかったら関数の動作は未定義と言っていますよね、
>それでもう一方では、C言語では正しいと言っていますが、あまり意味が分からないんですけどどういうことでしょう?

@ No. 680
最後にナル文字が存在しない場合,文字列を扱うCライブラリ関数の動作は全て未定義です。

@ No. 681
char ch[5] = "HELLO";
はC言語としては正しいですが,C++言語としては間違いです。

のことでしょうか?

言語自体の機能として,
N文字からなる文字列リテラルをN個のchar型要素からなる配列の初期化子として利用した場合,
最後のナル文字はないものとして初期化する,というものがNo. 681で書いたことです。

それに対して,
文字列はナル文字で終端し,終端していない文字列を渡したときの動作を未定義としているのは,
言語自体の機能ではなく,ライブラリの規約です。
#いくつかの例外を除く。


言語自体の機能とライブラリの規約は別物ですから,特別矛盾しませんよ。


No.689

Re:NULL文字の意味がいまいち分かりません。
投稿者---ソウスケ(2003/11/17 22:43:20)


なるほど・・・、ではコンパイラ自体は普通はエラーを出さないんですね、
で、実行したときにエラーがでると・・。
では僕のがちゃんとHELLOと表示されたのは表面上だけで、実際にはメモリ破壊みたいなことが起こっていると考えていいんですね?

No.690

Re:NULL文字の意味がいまいち分かりません。
投稿者---YuO(2003/11/18 18:52:18)


>では僕のがちゃんとHELLOと表示されたのは表面上だけで、実際にはメモリ破壊みたいなことが起こっていると考えていいんですね?

裏で何が起こっているかは全くわからない,というのが本当のところです。
未定義動作というのはそういうものですから。


No.691

Re:NULL文字の意味がいまいち分かりません。
投稿者---ソウスケ(2003/11/18 19:05:24)


どーもありがとうございます。



No.697

Re:NULL文字の意味がいまいち分かりません。
投稿者---RAPT(2003/11/25 22:56:59)


参考までに。

配列の初期化指定子において、
> char ch[5] = "HELLO";
は、
> char ch[5] = { 'H', 'E', 'L', 'L', 'O' };
の syntax sugar (文法糖) と言われます。

簡単に言うと、コードの入力や、コードを読むのを楽にするためのものです。


構造体をポインタで扱う時の、
struct tow_num{
int a;
int b;
} *ptr;

(*ptr).a と表記する代わりに、ptr->a と書きますが、
これも、syntax sugar (文法糖) です。


No.680

Re:NULL文字の意味がいまいち分かりません。
投稿者---YuO(2003/11/17 04:49:26)


>↓のソースを実行させると「HELLO」と表示されますよね、しかし語尾にNULL文字ははいっていないですよね。
>なぜ表示されるんでしょうか?

たまたまです。
最後にナル文字が存在しない場合,文字列を扱うCライブラリ関数の動作は全て未定義です。
結果としてハードディスクが初期化されたとしても,それは「間違っていない動作」のうちです。


No.682

Re:NULL文字の意味がいまいち分かりません。
投稿者---ceybord(2003/11/17 07:48:44)


今のプログラムの場合は、自動メモリの確保とprintfしかやっていないので、それほど深刻な結果は出ないと思いますが。
まぁ、要はC言語を使うときは、十分確認してから実行しろということですね。