【文字と文字列】
ちょっと、今までの復習です。
┏━━━━━━━━━━━┓
┃ char c; ┃
┃ ┃
┃ c = 'a'; ┃
┃ printf("%c",c); ┃
┗━━━━━━━━━━━┛
と記述すると、変数cの内容は 1文字の 'a' (ASCII コードの 61h)
になりますよね?
printf関数で1文字を表示したい時は %c を使えば表示できます。
つまり、上記のプログラムをコンパイル−実行すると
a
と1文字が表示されます。
┏━━━━━━━━━━━┓
┃ char* s; ┃
┃ ┃
┃ s = "abcdefg"; ┃
┃ printf("%s",s); ┃
┗━━━━━━━━━━━┛
次に、上記のプログラムをコンパイル−実行すると
abcdefg
と、文字列が表示されます。
printf関数で %s は文字列の表示でしたね!
プログラムの
s = "abcdefg";
の部分は
┏━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ "abcdefg" という文字列をメモリ上に用意して ┃
┃ 先頭アドレスをポインタ変数sに代入しなさい。 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━┛
という意味です。メモリ上のイメージを図にすると下のようになります。
(便宜上、文字列 "abcdefg"の先頭アドレスを100と仮定しています。)
アドレス
┏━━━━┓ 100 ┏━━━━━━━━┓
ポインタ変数s ┃ 100 ┃ ┃ a (61h) ┃ ()の中はASCIIコード
┗━━━━┛ 101 ┣━━━━━━━━┫
┃ b (62h) ┃
102 ┣━━━━━━━━┫
┃ b (63h) ┃
103 ┣━━━━━━━━┫
┃ d (64h) ┃
104 ┣━━━━━━━━┫
┃ e (65h) ┃
105 ┣━━━━━━━━┫
┃ f (66h) ┃
106 ┣━━━━━━━━┫
┃ g (67h) ┃
107 ┣━━━━━━━━┫
┃ \0 (00h) ┃
┗━━━━━━━━┛
実は、C言語には「文字列」を扱う型が用意されてなく、
内部的には「文字列」を表現するのに文字(char型)の
配列を使っています。そして、文字列の終端記号として
\0 (ヌル文字)が付加されています。
つまり、 '' で囲んだ1文字は 文字として解釈され
"" で囲んだ文字列は文字(char) の配列として解釈されて
文字の最後に \0 が付加されるのです。
【NULL と ヌル文字】
C言語では、0番地のことを NULL と表記しています。
この NULL はポインタ変数を初期化しておきたいときに
よく使われます。
例1)NULL ポインタ
┏━━━━━━━┓
┃ char *a; ┃
┃ a = NULL; ┃
┗━━━━━━━┛
つまり、NULL というのは
「このポインタ変数は、どこも指し示していません」
という意味です。
よく、混同されやすいのがヌル文字 ( '\0' ) です。
例2)ヌル文字
┏━━━━━━━━━━━━━━━━━━━━━━━┓
┃ char a[100] = { 'J','h','o','n','\0' }; ┃
┃ printf("%s\n",a); ┃
┗━━━━━━━━━━━━━━━━━━━━━━━┛
実は、C言語には「文字列」を扱う型が用意されていないのです。
「文字列」を表現するのに文字(char型)の配列を使います。
例2を実行すると
Jhon
と表示されますが、例2を下記のようにすると
┏━━━━━━━━━━━━━━━━━━━━━━━┓
┃ char a[100] = { 'J','h','o','n','\0' }; ┃
┃ ┃
┃ a[1] = '\0'; ┃
┃ printf("%s\n",a); ┃
┗━━━━━━━━━━━━━━━━━━━━━━━┛
表示が
J
となってしまいます。それ以降も文字列が表示されません。
これは、ヌル文字がC言語での文字列の終端を意味するからです。
char a[100] = { 'J','h','o','n','\0' };
の部分なのですが、意味は char 100 個の配列をメモリ上に
用意して
a[0] = 'J';
a[1] = 'h';
a[2] = 'o';
a[3] = 'n';
a[4] = '\0';
を行う、という意味です。1文字ごとの初期化になるので
"" を使ったときと違って文字列の最後には明示的に '\0' を
記述する必要があります。("" を用いた時はヌル文字が自動的に付加される。)
char a[100] = "Jhon";
としてもコンパイラには同じに解釈されます。
┏━━━━━━━━━━━━┓
┃ char a[] = "Jhon"; ┃
┃ 又は ┃
┃ char* a = "Jhon"; ┃
┗━━━━━━━━━━━━┛
と記述した場合は Jhon 4文字 と ヌル文字 1文字 の
5文字分のメモリエリアが確保されます。
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ┃
┃ 図1) char *a = "Jhon" とした場合のメモリイメージ ┃
┃ ┃
┃ ┏━━━┳━━━┳━━━┳━━━┳━━━┓ ┃
┃ ┃ 'J' ┃ 'h' ┃ 'o' ┃ 'n' ┃ \0 ┃ ┃
┃ ┗━━━┻━━━┻━━━┻━━━┻━━━┛ ┃
┃ └─────── 5 Byte ───────┘ ┃
┃ ┃
┃ 図2) char a[100] = "Jhon" とした場合のメモリイメージ ┃
┃ ┃
┃ ┏━━━┳━━━┳━━━┳━━━┳━━━┳━━━━━━━━━━━┳━━━┓ ┃
┃ ┃ 'J' ┃ 'h' ┃ 'o' ┃ 'n' ┃ \0 ┃・・・・・・・・・・ ┃ ・ ┃ ┃
┃ ┗━━━┻━━━┻━━━┻━━━┻━━━┻━━━━━━━━━━━┻━━━┛ ┃
┃ └─────── 100 Byte ──────────────────────┘ ┃
┃ ┃
┃ ※ ・で表記している部分は初期化されていない不定な値 ┃
┃ ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
【今回のまとめ】
・C言語では、文字列は char型 の配列で表現されている。
・文字列の終端には ヌル文字 ('\0') をつける。
・変数に1文字を 代入するときは '文字' で行う。 (例. char c = 'A'; )
・文字列を扱うときは "文字列" の形式でポインタ変数で受け取る (例. char* s = "ABCDEFG"; )