こんにちは､ ようこそ｡
この講義では､ 配列の初期化についてお話したいと思います｡
配列の使い方も､ 配列の作り方も知っています｡
しかし､ 具体的に､ 配列に特定の初期値を割り当てたい場合は､ どうすればいいのでしょうか｡
そのため､ ほとんどの場合､ 配列の要素に初期値を割り当てたいと思うでしょう｡
配列､ あるいは変数に初期値を割り当てる理由は､
物事がうまくいかなくなったときに発見しやすくなるためです｡
初期データがない状態で､ 何かをしようとすると､ プログラムに不具合が生じることがあります｡
ですから､ 初期化はとても良いことで､ 必ず行いたいものです｡
そして､ 配列を使うと､ 配列の中に何個も何個も要素があるんです｡
そのため､ それらの要素を初期化する方法が決まっているのです｡
使える構文が違うんです｡
しかし､ 初期化は良いことなので､ 必ず行いたいものです｡
配列のやり方はいろいろあるので､ 手短にお話ししたいと思います｡
つまり､ 変数の宣言時に初期値を設定するのと同じように､
配列の宣言時に配列の要素に初期値を設定することができるのです｡
配列の値を初期化するには､ 単純にリストで値を指定します｡
リストはカンマで区切られ､ リスト全体は中括弧で囲まれる｡
このような感じです｡
ここでは､ countersという名前の配列を作成しています｡
int型で､ 5つの要素を持っています｡
そして､ 中括弧で囲んでいますが､ ここではインデックスを使用していません｡
カンマで区切られた数字だけであることにお気づきでしょうか｡
これは何をやっているかというと､ カウンタ配列の5つの要素をすべて0に設定しているのです｡
別の配列があり､ その配列の名前を整数とし､ サイズを5とした場合､
代入演算子の後に中括弧で0カンマ1カンマ2カンマ3カンマ4とすると､
これはどうなるのでしょうか｡
第1要素のinteger配列に0､ 第2要素に1､
第3要素に2､ 第4要素に3､ 第5要素に4を代入しているのです｡
カッコの中にカンマで区切られた数字を入れるだけで､ 宣言したときにすぐに配列を初期化できるいい構文で､
こんなことをやりたくなります｡
また､ 配列全体を完全に初期化する必要はありません｡
つまり､ 先の2つの例では､ サイズ5の配列の5つの要素をすべて初期化したことになります｡
一部の値だけを初期化したい場合はどうすればいいのでしょうか？
配列のサイズと等しくない初期値を指定した場合､
残りの値は0に設定される｡
ですから､ このようにflow型のサンプルデータという配列があったとして､
その中には500個の要素が含まれています｡
しかし､ 中括弧の中にあるのは､ ここにある3つの要素だけです｡
これは､ サンプルデータ配列の最初の3つの値を100
300 500に初期化するものです｡ 5.
そして､ 残りの5 497個の要素が0になる｡
だから､ すべてを指定する必要はないんです｡
また､ この指定イニシャライザーという概念もあります｡
これはC99で導入されたと思います｡
初期化したい要素を選べるのは嬉しい機能ですね｡
C99で追加され､ C11でオプションになったのだと思います｡
ですから､ どのようなコンパイラーを使用しているかによって､ これができるかできないかが変わってきます｡
でも､ なんとなくありがちなので､ 触れておきたいと思います｡
C99以降では､ これを許さないコンパイラもあります｡
でも､ 実際には選ぶだけでいいので､ かっこいいですよね｡
つまり､ 要素番号を括弧で囲んでから､ 初期化できる配列要素を指定すれば､
どのような順番でも可能です｡
そこで､ 一例をご紹介します｡
ここでも､ サンプルのデータ配列があります｡
タイプはfloatです｡
サイズは500になる予定です｡
しかし､ ここでは中括弧の中に､ さらにインデックスを追加しています｡
私たちは､ ブラケットを2つ持っていて､ ブラケット2サブ2が500に等しいと言っています｡ 5､ sub-1は300に相当します｡
0､ sub-0は100に相当します｡ 0.
カンマで区切られています｡
これは､ 前の例と同じものを指定しているのですが､
順番が違います｡
しかし､ 要素0または1番目の要素が100に等しく､ 2番目の要素が300に等しく､ 3番目のアルバムが500に等しいことに変わりはないでしょう｡
5.
しかし､ 中括弧の中で､ どのインデックスを初期化するかを指定しているのです｡
別の例として､ arrというint型の配列があり､ そのサイズは6です｡
そして宣言すると､ 最後の要素である5番目の要素を212に初期化し､
すべての要素が0になるようにしているのです｡
そこで､ 従来の初期化の例として､ 配列の名前を宣言するだけで､
さまざまな数値が供給される例を示します｡
この例では､ 配列を宣言して､ 各月のすべての日を格納しています｡
この配列を調べてプリントアウトするのはよくあることですが､
通常はループを使って配列の要素をプリントアウトするか､ 少なくとも反復処理を行います｡
ここでやっているのは､ 各月とその日数をプリントアウトすることです｡
では､ これをコードブロックで出力してみましょう｡
では､ その例をご紹介しましょう｡
日と月があり､ 配列を初期化しています｡
最初の要素が31､ 次の要素が28､ 次の要素が31になるように｡
また､ 10行目ではdefineを使って定数を作っていることに気づきました｡
ところで､ C言語では定数キーワードを使うこともできますが､
これについてはまた別の機会に説明します｡
でも今は､ 配列とその初期化について話しているだけで､
中括弧の中のカンマで区切れば､ とても簡単にできます｡
つまり､ 配列のインデックスに1を足した値を表示し､
その後に日数分のインデックスを表示します｡
つまり､ 値に応じて月1は何日目ということになります｡
つまり､ 配列名でインデックスにアクセスし､ 添え字の値､ インデックス値で､
配列を使っているわけです｡
つまり､ 繰り返しのたびに変化する変数なんですね｡
そこで､ これを実行しようとする｡
出力されるのは､ 1ヶ月目が31日､ 2ヶ月目が28日で､
1月2月3月4月を表しています｡
つまり､ これで初期化がうまくいったことが証明されたわけです｡
そしてまた､ データを初期化することになります｡
では､ 別の例として､ 初期化要素の繰り返しについてお話します｡
ここでは別の例を示しますが､ この例では指定されたイニシャライザーを使用することにします｡
初期化する要素を正確に指定するのです｡
ここで注目すべきは､ 「日」と「月」に分かれている行で､
初期化を行っているところです｡
中括弧の中には､ 最初の要素が31､
2番目の要素が28､ そして括弧の中に4と書かれているものがあり､ それは値31を取得することになることに注意してください｡
そして､ コンマで､ 要素5が30､ 要素6が31になるようにします｡
そして､ 1.
つまり､ これから28を上書きして､ 実際に29を入れる､ 29と入れるということです｡
だから､ ここではちょっと冗長なんです｡
その必要はないのですが､ 31と28､ サブ1がすでにここに割り当てられているので､
サブ1を本当に削除してしまうのです｡
しかし､ サブ1は値29にもなると言っているようなものです｡
つまり､ これは指定されたイニシャライザーを使っているだけなのです｡
同じ値を繰り返す場合はどうでしょう｡
さて､ cでは､ 0を指定すれば､ 常に同じ値の配列全体を初期化することができます｡
ヌルパラメーターと同じように常に初期化することができます｡
しかし､ それ以外には､ 少なくともC89では､ cは配列要素の初期化のためのショートカット機構を提供していないのです｡
C11でも､ 添え字なしの数字だけの大括弧を使って､ 配列全体を同じ値で初期化することができますね｡
しかし､ 今のC89とC99では､ リピート回数を指定する方法がない｡
例えば､ このレイの要素はすべて55であるべきだ､ などということはあり得ないのです｡
そのため､ サンプルデータの500個の値をすべて1に設定しようとすると､
500個すべてを明示的に代入しなければならず､ 大変な手間がかかる｡
結局のところ､ ループの中に入れるだけなんですね｡
配列を反復処理する最も簡単な方法は､ ループを使うことです｡
では､ すべての要素を同じ値で初期化する方法を簡単に説明します｡
この場合､ 最初の要素は0 1 4
9 16と初期化されますが｡
つまり､ これは単に残りの要素をすべて値で初期化しているだけなのです｡
インデックス5～9を使用した第10エレメントの第6エレメントを基本としています｡
つまり､ このforループがやっていることは､ そういうことです｡
最初のforループは､ 5から9までの要素をI×Iに初期化すると言っているのです｡
それから､ 2つ目のforループはインデントしたほうがいいですね､
読みにくいですから｡
2番目のforループは､ 実際に配列全体を通過して､
最後の5つの値が実際に初期化されたことを示すためにデータを表示しているだけです｡
だから､ 同じ値を繰り返したいときや､ 異なる値に初期化したいときは､
いつでもループを使えばいいのです｡
ここでも初期化が重要です｡
初期化する必要があるので､ この構文が自然に身につくようにしてください｡