これまでも散々扱ってきた文字列について改めて・・・。
文字列は、
- 文字列リテラル
- 文字配列
に分けられる・・・。
文字列リテラルは、任意のメモリが確保され、それぞれの文字が指定の文字に固定される・・・。
プログラム中でメモリを確保していないので、この文字を変えることはできない・・・。
文字配列はプログラム中でメモリを確保し、そこに文字を入れているため、文字を変更することもできる・・・。
str2は配列としての宣言をし、その文字列を"str2ABCDE"として初期化している・・・。これをいじることは可能である・・・。それはあとでやるとして・・・。
一方の、str3はポインタで文字列リテラルを指している・・・。文字列リテラルは固定で変更できないので、str3の指す文字列をいじることはできない・・・。
まず、str1の入力・・・。"ABCDE"と入れよう・・・。
そして、すかさずstr1を出力・・・。
ここまでで、
$ ./string str1: ABCDE str1 = "ABCDE"
となることはわかるだろう・・・。
文字配列str1の中身を確認している・・・。
str1[0]: 'A' str1[1]: 'B' str1[2]: 'C' str1[3]: 'D' str1[4]: 'E' str1[5]: '' str1 end.
ここには表示されていないが、str1[5]には文字列の終端記号であるNULL文字'\0'が入る・・・。これがみつかったらループを抜けるようにしている・・・。
これが存在することで、ここで文字列が終わることを認識できる・・・。
str2も中身を確認する・・。str2は文字列の長さが10(NULL文字'\0'を含む)なので、10回ループして1つずつ文字を確認する・・・。
str2[0]: 's' str2[1]: 't' str2[2]: 'r' str2[3]: '2' str2[4]: 'A' str2[5]: 'B' str2[6]: 'C' str2[7]: 'D' str2[8]: 'E' str2[9]: ''
str2[9]もNULL文字・・・。
さて、このstr2の0から数えて4番目にNULL文字を入れるとどうなるだろうか・・・?
str2 = "str2ABCDE" str2 = "str2"
このように"ABCDE"はカットされる・・・。
"str2"の後ろにNULL文字が入ったので、printfは"str2"までが文字列だと認識しているのである・・・。
str2の中身をまた確認しよう・・・。
str2[0]: 's' str2[1]: 't' str2[2]: 'r' str2[3]: '2' str2[4]: '' str2[5]: 'B' str2[6]: 'C' str2[7]: 'D' str2[8]: 'E' str2[9]: ''
実際には、"str2"とNULL文字のあとには、"BCDE"が残っていることがわかる・・・。
このようにNULL文字を入れることで、表示上の文字列を短くカットできる・・・。
しかし逆に考えると、プログラム中で文字列が途中で切れるような問題が発生した場合は、その原因がNULL文字にある可能性が高いともいえる・・・。
最後にstr3の文字列リテラルを指すポインタ、およびその文字列の中身も表示している・・・。
str3 = "str3" *(str3 + 0): 's' *(str3 + 1): 't' *(str3 + 2): 'r' *(str3 + 3): '3' *(str3 + 4): ''
まとめると、
- 文字列リテラルは変更不可、文字配列は変更可
- 文字列の終わりにはNULL文字'\0'が入る
- NULL文字を文字列の途中に差し込むと、文字列が見た目上は短くなるが、後ろの文字は残る
こんな感じ・・・。