多次元配列 配列の配列が作れる 普通の変数は 0 次元 k 次元の要素の配列は k+1 次元 配列: すでにあるデータ構造から、それが並んだ新しいデータ構造を作る 構造体: すでにあるデータ構造から、それを組み合わせた新しいデータ構造を作る 配列や構造体を使って作ったデータ構造は、 次のデータ構造を作るための材料になる 多次元配列 配列から配列を作る # 二次元の配列が行列 より一般に 配列から構造体 構造から配列 => いくらでも複雑な組み合わせが可能 新しいデータ構造を作る union ポインター == [復習] 文字列について C 言語では、「文字列」は、 「"(ダブルクォーテーション)」で挟まれた文字列 「文字列」は、関数の実引数に指定する事ができる # 最初の Hello World で、printf に指定している 仮引き数変数の宣言には、(説明無しに..) 「char *」とする !! 「char *」が「文字列」を表す 文字列の操作 文字列から文字の取り出し 文字列の頭に * をつけると、先頭の文字が取り出せる 文字列に +1 すると、 文字列の先頭の文字がなくなり、一文字短く 上記を組み合わせて *(文字列 + n) => 文字列[n] => n 番目(0 から始めて..) !! 文字列は、文字の並びで、最後に EOS('\0') がある *(a+n) <-> a[n] 添え字 文字列 n 番目の文字を取り出す 配列 配列の n 番目の要素を取り出す => もし、「文字列」が「文字配列」であれば、 不思議はない 「文字列」は「文字の並び」だから、「文字配列」 C 言語では、 「文字列」は、「文字の配列」+ EOS からできている C言語のプログラム中に、 "abc" (文字列リテラル) という文字列を書くと、 どこかに、サイズ 4 の文字配列が作られ、 その中身が、'a', 'b', 'c', EOS になっている => 文字配列 => ただし、この「文字列」を表す文字配列は、 その「要素の値を変更」できない => 文字配列と異なる 関数の引数にリテラルを指定する時に注意 文字配列を「文字列」として扱う事もできる 「文字列を入力する」には、 「文字配列」に、「文字」と EOS をいれればよい これを実現するための命令 できるがやってはいけない方法 scanf ( "%s", 配列名 ); gets( 配列名 ); => 配列のサイズを知る事ができない 配列のサイズを超える入力をしてしまう可能性がある => 危険 : buffer over run という典型なミス => セキュリティ上の穴になる # コンピュータウィルス感染の原因 推奨されるのは、fgets を利用する fgets ( 配列名, サイズ, stdin ); => きちんと、サイズを渡しているので、 buffer over run を避ける事ができる !! fgets をつかうと、改行も読み込まれる 関数の引数に、配列名を指定するとどうなるか ? => 関数内で、「配列の要素の値」を「変更」できる <<復習>> 関数の実引数で指定された「値」は、 関数の仮引数変数に代入される 関数の実引数に、配列名を指定し、 関数内で、その配列要素の値を(当然、参照ができるだけでなく) 変更する事ができる => 関数呼び出しによって、関数の呼び出し側の変数の値が 書き変わってしまう可能性がある 得失 失: 関数呼び出しによって、(しらぬまに..) 変数の値が変わる -> わかりにくい 得: 関数によって、配列の要素の変更可能 => 文字列の入力が、関数呼び出しによって、可能になっている !! 「配列名を指定する」 実引数に配列名を指定すると時の、 仮引数変数の宣言の仕方 素直だが、推奨されないのは、 実引数と同じ形の宣言 配列の最初の添え字のサイズを省略するパターン 基本の表現 # 多次元配列の配列名を引数にする場合は、 # この書き方だけが正しい書き方 一次元配列の場合だけは、 [] を仮引数変数の後ろに書く代わりに、 仮引数変数の前に * を付ける流儀が許さるし、 そちらの方が、望ましい。