C言語基礎|文字配列の初期化

「文字列づくりは一瞬で! char配列の初期化で、\0 まで“確実”に入れよう」

1文字ずつ代入は卒業しよう

文字列を作るたびに

  • str[0] = 'A'
  • str[1] = 'B'
  • str[2] = 'C'
  • str[3] = '\0'

…と書くの、正直ちょっと面倒ですよね。
C言語には、宣言と同時に配列を初期化して、文字列を一発で作る方法があります。

ここを押さえると、コードが短くなるだけでなく、終端のナル文字 \0 を入れ忘れる事故も減らせます。やさしく整理していきますね。

文字配列の初期化とは

初期化の意味

初期化は「配列を作った瞬間に、最初の値をまとめて入れること」です。
配列の場合、初期化は 宣言のところでだけできます(あとからまとめて代入はできません)。

初期化の書き方は大きく2種類

1 文字配列を初期化する2つの基本形

形式特徴
文字を1個ずつ並べるchar str[] = {'A','B','C','\0'};中身が見えて分かりやすい。終端0を自分で書く
文字列リテラルで初期化char str[] = "ABC";基本はこれ。終端0は自動で付く

表の説明
上は配列の一般的な初期化(int配列などと同じ発想)です。
下は文字列専用の便利ルールで、"ABC" と書くだけで最後に \0 まで入ります。

"ABC" で本当に \0 まで入るの?

入ります。つまり、次の2つは同じ内容です。

  • char str[4] = {'A','B','C','\0'};
  • char str[4] = "ABC";

メモリ上のイメージ("ABC")

図の説明
printf の %s は、先頭から最初の 0(ナル文字)までを文字列として表示します。だから \0 はとても大事な“終端マーク”です。

要素数を省略できる理由

次のように、要素数を書かない形がよく使われます。

  • char str[] = "ABC";
  • char str[] = {'A','B','C','\0'};

これは 初期化子の個数から配列サイズが決まるからです。

要素数省略時に決まるサイズ

初期化入る要素配列サイズ
char str[] = "ABC";A, B, C, 04
char str[] = "A";A, 02
char str[] = "";01

表の説明
空文字列でも終端0が必要なので、サイズは1になります。ここ、地味に大事です。

よくある注意:あとから初期化子を代入はできない

配列は「まとめて代入」ができません。文字列でも同じです。

ダメな例(エラーになる)

コードなぜダメ?
char s[4]; s = "ABC";配列そのものは代入できない
char s[4]; s = {'A','B','C','\0'};初期化子は宣言時専用

表の説明
配列は“箱の列”そのものなので、箱の列をまるごと付け替える代入はできません。宣言時に初期化するか、あとからなら要素ごとに入れます(または文字列関数を使いますが、ここではまだ触れなくてOKです)。

サンプルプログラム

配列の初期値を"OK"とするプログラムです。

プロジェクト名:chap9-3-1 ソースファイル名:chap9-3-1.c

// 文字配列を初期化して表示する

#include <stdio.h>

int main(void)
{
    char msg[] = "OK";

    printf("初期化した文字列は【%s】です。\n", msg);

    return 0;
}

この例のポイント

  • msg は char の配列
  • "OK" の末尾に \0 が自動で付く
  • %s で文字列として表示できる

char 配列の初期化(宣言)

  • 書式(代表)
    • char 配列名[要素数] = { 初期値1, 初期値2, ... };
    • char 配列名[要素数] = "文字列";
    • char 配列名[] = "文字列"; (要素数省略)
  • 何をする?
    • 配列を作ると同時に、中身を最初から決める

演習問題

演習9-1

次の宣言を使うと、表示はどうなるか考えてみましょう。

char str[] = "ABC\0DEF";

解説(結論)

  • 配列の中身は A, B, C, 0, D, E, F, 0 になります(末尾にも0が付く)
  • でも %s で表示されるのは 最初の0までなので、見える文字列は ABC までです

"ABC\0DEF" の中身と見える範囲

図の説明
途中に0があると、そこが“文字列の終わり”になります。後ろにDEFが入っていても、%s はそこまで読みません。