配列は大量のデータを扱うのに便利ですが、宣言直後は値が不定なので初期化が必要と、前回説明しました。この配列の初期化に関してはいろいろの方法が C言語では用意されています。その初期化方法について解説します。
--
いきなりここに飛んで来ちゃった人は、よろしければ下記からご覧ください。


  • 配列の初期値を与える
配列の宣言時に {} で複数の値を同時に指定する事が出来ます。

int number[5] = { 50, 40, 30, 20, 10 };

これで添え字の順番に応じた初期値が入ります。number[0] は 50 になっていますし、number[4] は 10 が格納されています。この初期化用の数値の事を初期化子と呼びます。では、初期値子の数が不足していたらどうなるでしょうか。例えば…

int number[5] = { 50 };
この結果、number[0] だけが 50 となり、それ以外は全て 0 になります。この 0 での初期化は保証されていますので、全てを 0 クリアとするならば、

int number[5] = { 0 };
このように記述すれば実現します。int 以外の型でも 0 でクリアされます。float だと 0.0F になります。また、初期化子を指定した場合は、配列要素数を省略できます。

float physics[] = { 3.14F, 9.8F, 8.314F };

この場合は、初期化子の数が 3個なので、配列の要素数は 3 で宣言されます。
※ 以前紹介した白色のスピーカーのブラックタイプです。有線なので音が途切れません。コストパフォーマンスは最高です。モニター内蔵スピーカーに不満な人は是非。

  • 文字配列
先にどんな型でも不足している要素は 0 でクリアされると説明しました。では、キャラクタ型である char で初期化するとどうなるでしょうか。

char str[10] = { 'A', 'B', 'C' };
ステップ実行して様子を見てみると、"ABC" という文字列が見えるだけになっています。
キャラクタ配列の初期化
初期化した 3文字しか見えないので不安になりますが、要素数として 10 が指定されているので、配列としては 10個分取得されているはずです。これを確認するには、ローカルまたは自動で表示されている str 変数左の ▶をマウスでクリックします。配列が展開されて詳細が見えます。
キャラクタ配列を展開表示
添え字 [0],[1],[2] はそれぞれ最初に指定された文字が格納されていますが、それ以外の場所は 0 でクリアされているのが確認できます。

C言語では、文字の集まりを文字列として扱っています。その文字列の終端は 0 となっていますので、文字配列では最初から 0 までを文字列と見なします。そのため、VS2022 のデバッガでは "ABC" と表示しているというワケです。str には "ABC" という文字列が格納されていると言い換えても問題ないです。そのため、

char str[10] = { 'A', 'B', 'C' }; printf("%s", str);
このように書式文字列 %s を指定する事で、配列に格納された文字列を画面に表示させる事が出来ます。もちろん、0 で表示が止まりますので、画面には ABC とだけ表示されます。先に、初期化子を与えると、配列要素数を省略できると説明しましたが、文字型で要素数を省略するとどうなるでしょうか。

char str[] = { 'A', 'B', 'C' };
はい、3個用意したので、配列としては 3個の要素数として確保されます。ただ、終端コードがないので、文字列としては不適切となります。実際、VS2022 のローカルには、ABC... と表示され、文字列としては止まっていない事が示唆されます。
※ 文字列として認識されている場合は "ABC" とダブルクォートで括られて表示されます。

終端文字がない文字配列は文字列として扱えない
これを printf すると、
終端がないのでゴミが表示さ
ABC の後ろに フフフフフ...と表示されました。これ、Debug実行なので フフフフフ... と表示されてます。キャラクタ文字 フ は 0xCC なのです。そして、Debug実行では未定義領域はテスト用に 0xCC で初期化されていますので、フフフフフ...と表示されるのです。
※ VS2022 から笑われているのではないです😁

Release実行すると、何が表示されるかは保証がないです。私の環境ではたまたま ABC ときちんと表示されましたが、それはあくまでもたまたまです。0 が見つかるまで、よく分からない文字を表示し続けるかもしれないのです。

このような事態を防ぐためには、文字配列の初期化子は文字列とするのが良いです。先の例では

char str[] = "ABC";
これで、str には 4個の要素が用意されます。str[3] には 0 が入ります。これなら、VS2022 のローカルには "ABC" と文字列として表示されますし、種類にも char[4] と 4個の要素が存在すると表示されます。当然、printf("%s", str); としても、正常に ABC と表示されます。

配列の初期化子に文字列を使って際に、文字列の文字数が不足している場合は、足りない分は 0 クリアされます。では、配列要素数より多い文字数の文字列初期化子を与えた場合はどうなるでしょうか。VS2022 の場合はビルド前にエラーとして表示されます。
エラーとなり正常にビルドできない
過去の C言語だとコンパイルして実行出来るかと思いますが、この指定は不正メモリアクセスとなります。メモリ内の何かを破壊しますので大変危険です。VS2022 を使っているのであれば、静的解析により事前にエラーとなりますが、他の環境ではうっかりするとやってしまいがちなので、気をつけたい部分となります。
Creative Inspire T10 R3 スピーカー IN-T10-R3
クリエイティブ・メディア
2016-01-20
※ もうちょっとお金を出しても良いのでもっと良い音をお求めの場合はこちら。聞き比べるとその差は歴然。それでも安いです!

  • 文字列の入力
文字配列を用意すれば文字列が扱えます。そのため、scanf_s で文字列を入力する事が出来るようになります。以前は使用できた scanf という命令が事実上撤廃されて、現在は scanf_s になっている主な理由がこの文字列入力です。少し試してみましょう。

char name[10]; printf("あなたの名前を入力してください。\n"); scanf_s("%s", name);
このように記述すると、char に文字列を入力する事が出来ます。では、ここに NAITOTokihiro と 10文字を超える文字を入れてみます。すると…
配列要素数を超えた入力は例外となる
このように例外が発生しました。セキュリティとして大変マズイ、バッファオーバーランという状態を未然に防いだ形となります。以前の scanf ですと、配列要素数を超えて文字が入力できてしまったため、任意の文字列でメモリを食い潰して、対象のコンピュータに自分の意図する任意のプログラムを動かす事が出来てしまっていました。これを防ぐのが scanf_s です。例外を防ぐには、scanf_s の第3引数に最大文字数を指定します。先の例ですと

char name[10]; printf("あなたの名前を入力してください。\n"); scanf_s("%s", name, 10);
このように記述します。NAITOTokihiro と長い文字列を入力すると、name の配列には先頭に 0  が入るだけになります。NAITOToki と9文字入力すると、終端コードと合わせて 10文字分が name に入力されます。


  • おまけ情報
■ 初期化の省略

int number[5] = { 0 };
こちらですが、省略したら 0 でクリアされるので、本当は…

int number[5] = {};
このように記述しても同じように全て 0 でクリアされます。ただ、全てを 0 で消していると明確化するため、私は { 0 } と記述する事を推奨します。{} だけでは分かりにくいと思いませんか?

■ 文字列の表示

printf("%s", str);
こちらですが、他の表示対象が無い場合は、そのまま…

printf(str);
このように省略して記述できます。

■ 入力文字数の指定

char name[10]; scanf_s("%s", name, 10);
配列要素数 10 と文字入力最大数の 10 という直値が二つも記述されています。これはマジックナンバーと言って将来のバグを引き起こす可能性がある、プログラマには忌み嫌われている記述となります。この場合は事前に個数を定数化するか

#define MAX_NAME 10 char name[MAX_NAME]; scanf_s("%s", name, MAX_NAME);
sizeof を使用して配列の要素数を取得すると良いでしょう。

char name[10]; int count = (int)(sizeof(name) / sizeof(char)); scanf_s("%s", name, count);
sizeof は本来はバイト数の取得で要素数の取得ではありません。そのため、取得したサイズを型のサイズで割って、正しい要素数を取得しています。VS2022 では _countof というマクロが用意されているので、そちらを使うと幸せになれるかもです。
※ PC再生で至高のの音質を目指し、かつ、リーズナブルな価格帯となるとこちらをオススメ。ヤマハの音作りが嫌いじゃなければ最高です!