トラック9・🔤文字列

ヌル終端 '\0' の掟

読む目安 約14分・ゴール:ヌル終端の役割を理解し、必要な配列サイズを正しく見積もれる

アプリでこのトピックを学ぶ(無料・登録不要)

このトピックの要点

char s[6] = "hello"; で6個ぶん必要だった理由を明かします。文字列の最後には、必ずヌル文字 '\0' が置かれるからです。

 s[0]  s[1]  s[2]  s[3]  s[4]  s[5]
+-----+-----+-----+-----+-----+-----+
| 'h' | 'e' | 'l' | 'l' | 'o' |'\0' |
+-----+-----+-----+-----+-----+-----+
                              ここまでが文字列、という印

'\0' は値が0の文字です。数字の '0'(値48)とは別物なので、混同しないでください。画面には何も表示されず、ただ「ここで終わり」を意味します。

なぜ印が必要なのか

配列を渡されただけでは、どこまでが文字列なのか誰にも分かりません。Cは配列の長さを覚えていないからです。そこで終わりに目印を置くという約束を作りました。printf の %s も strlen も、この印に出会うまで前から順に読み進めます。

#include <stdio.h>
#include <string.h>

int main(void)
{
    char s[6] = "cat";

    printf("%zu\n", sizeof(s));    // 6 ← 箱の数(確保した大きさ)
    printf("%zu\n", strlen(s));    // 3 ← 文字数('\0' の手前まで)
    return 0;
}

sizeof と strlen の違いは頻出です。箱の数と中身の文字数は別、と覚えてください。char s[6] = "cat"; の場合、s[3] が '\0' で、s[4] と s[5] も 0 で埋められます。

下のビジュアライザで、1文字ずつ '\0' を探しに行く様子を見てみましょう。

🧪 メモリの図解:この図はアプリ内で1行ずつ動かせます。アプリでこのトピックを開く

印を失うとどうなるか

char s[5] = "hello";     // 5文字ぴったり。'\0' が入らない!
printf("%s\n", s);       // どこまで読むか分からず暴走する

これはコンパイルが通ってしまいます。printf は '\0' を探して配列の外まで読み進め、たまたま見つかった 0 までを表示します。文字化けするか、境界外アクセスで異常終了するか、運が良ければ何事もなく動く——おなじみの未定義動作です。

罠・注意

師範Cの文字列に長さは書かれておらん。終わりの印だけが頼りじゃ

まとめ: 文字列の最後には必ず '\0'。配列は「文字数+1」で確保し、sizeof(箱の数)と strlen(文字数)を区別する。

アプリでこのトピックを学ぶ(無料・登録不要)

確認問題

確認問題 1

文字列の末尾に置かれる '\0' の役割はどれですか。

  1. 文字列の先頭を示す
  2. 画面に0を表示する
  3. 文字列がここで終わることを示す
  4. 文字列の長さを数値で記録している
答えを見る

正解:C(文字列がここで終わることを示す)

'\0' は値0の文字で、「ここで終わり」という目印です。Cは配列の長さを覚えていないので、printf も strlen もこの印に出会うまで前から読み進めます。数字の '0'(値48)とは別物です。

確認問題 2

次のプログラムの出力はどれですか。

#include <stdio.h>
#include <string.h>

int main(void)
{
    char s[10] = "cat";

    printf("%zu %zu\n", sizeof(s), strlen(s));
    return 0;
}
  1. 10 3
  2. 3 3
  3. 10 10
  4. 4 3
答えを見る

正解:A(10 3)

sizeof は確保した箱の数なので10、strlen は '\0' の手前までの文字数なので3です。「箱の数」と「中身の文字数」は別物、という区別がここで問われます。

「文字列」の目次

  1. 文字列とはchar配列である
  2. ヌル終端 '\0' の掟
  3. 文字列リテラルと初期化
  4. string.h の主要関数
  5. 安全な文字列操作——バッファサイズの意識
  6. 文字の判定と変換(ctype.h)
  7. 文字コードの基礎——ASCIIとUTF-8
  8. 文字列処理の定石パターン

もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。

完全版の販売ページは準備中です。

ほかのトラック

📚 姉妹教材:手を動かして覚える Linux 教材 — Linuxとインフラの仕組みを地図で学ぶ

Web版