前回の内容 : データ構造 (4) 講義 「文字列」と「文字型配列」 文字型配列 ( 文字型の配列 ) # 配列の要素が文字型のもの # char cary[4]; # cary[0], cary[1], cary[2], cary[3] # 'a' 'b' 'c' '\0' 文字列 「"(ダブルクォーテーション)」で挟まれた文字の並び "abc" = { 'a', 'b', 'c', '\0' } # '\0' は NUL 文字 ( 画面に表示する文字に対応しない事が保証されている ) # EOS ( End Of String : 文字列の終わり ) として使われる 文字配列に、文字列と同じようなデータ(文字コードの並び)を 保存(代入)すれば、あたかも、文字列のように振る舞う 「文字列」は、内部的には、文字列型配列に、その文字列を 構成する文字と、EOS が保存されているものとして実現されている <<注意: 文字配列と文字列の違い>> 文字型配列の要素(変数)には、代入が可能 文字列の要素には代入できない ( 文字列の中身は変更できない ) # 文字列(リテラル)は、変数の並びではなく定数の並び # => 「変更不能」なものからなっている !! 変更可能な文字列(のようなもの)が必要ならば、 !! 文字配列を用いればよい 文字配列と文字列は、同じような演算が可能 「配列名」と文字列リテラルは関数の引数に渡せる +1 すると、先頭の文字が取り除かれる * をつけると、先頭の文字が取り出せる *(文字列+n) = 文字列[n] *(配列名+n) = 配列名[n] 関数の実引数として指定される配列名(文字列) !!! 関数の引数に配列名を指定する事により、 !!! 関数の中で、配列の要素の値を変更できる fgets と「文字列」の入力 == メモリモデル 1 byte の情報が記録できるセルがたくさん並んだもので 一つセル : 変数と同じ振る舞いをする 代入可能で、記録を書き換える事(代入)ができる 記録されている情報(データ)は書き換えるまで、何度も取り出せる セルには、番地がついている セルを区別するには、番地の違いに着目すればよい C 言語の変数は、 メモリでモデルで説明できる 特に、文字型配列は、一個のセルとそのまま対応している C 言語の変数には、番地がついている 変数の前に「&」をつけると、 番地を得る事ができる !!! 「&」は以前に scanf の所で現れた !!! => その時は、「そうゆうもの」として「おまじない」にした !!! => 説明しなかった !!! 実は、「変数の番地を取り出す」という演算子 番地は数値(データ)なので、 関数に引数経由で渡す事ができる 逆に、配列の場合は、すでに配列名が、番地なので、 & をつける必要がない fgets の時も、配列名だけを指定 !!! セルの内容を変更するには、番地がわかればよい !!! => C 言語でも、呼び出し側の変数の番地を関数に渡す事により、 !!! その変数の値を、呼び出された関数内で変更可能 !!! 1) scanf がなぜ、変数の値を変更できるか !!! => 番地を渡しているから !!! => 変数の前に「&」が必要な理由 !!! 配列名を渡すときも同じ !!! 「配列名」は、「配列の最初の要素」の番地(の値を持つ定数) !!! 関数の引数に「配列名」を指定する事により !!! 配列の要素の値が変更できる 文字型の変数は、一個のセルに対応している 文字型のサイズは 1 (byte) という 他の型(のほとんど..)は、複数のセルから一つ変数が構成されていて、 サイズは、そのセルの個数 変数に & を付ける事により、番地(単なる数値ではない)を得る事ができる => printf の %p で表示可能 +1 をすると、その番地に入っている変数の型のサイズだけ増えるもの 「&によって得られた数値」は、「(単なる)整数値」ではなく、 型の情報をもったモノである => ポインター値 = 番地 + 型の情報 型の情報 サイズ(メモリ上でいくつのセルが必要か) 演算をするときに、どの振る舞いをするか ? 「*」を付ける事により、その型の変数と同じ振る舞いをする 型の異なる代入 double 型の値を int 型の変数に代入 値の型変換 ( double -> int ) double 型と int 型の混在している計算式では、 まず、int 型の値を double 型にして、 その double 型の変数で計算を行う。 # 型の昇格