2019/12/20 前回(2019/12/13)の内容 ポインター値 : メモリモデルのアドレスの抽象化 # 単なるアドレス値(番地番号)だけでなく、「型の情報」も持っている ポインター値 = アドレス値(番地番号) + (その番地にあるセルの並び[「変数」に対応]の保持するデータの)型情報 => ポインター値を利用して、「変数」を参照(値の取り出しや代入) ポインター値そのものの操作が可能 +n (n が整数の時) => ポインター値の持つ型の配列の n 個数先の要素の番地番号になる => 配列との相性がよい ary[n] <-> *(ary + n) 例 : int iary[10]: iary[5] <-> *(iary + 5) 左側: 整数型配列の 5 番目の要素を参照 右側: 配列の先頭要素に「5」を加えたポインター値が指す領域 => 番地としては、iary に対して 5 * sizeof(int) だけずれたものになる ポインター値の演算 整数値の加減算 : +1 するとアドレス値が領域サイズだけ増える アドレス値(番地番号)の操作 キャスト : 型情報を変更する事ができる 型情報を制御 => 「配列名」=> 配列の先頭の要素を指すポインタ値 配列 iary[10] の時、「iary <-> &iary[0] = &*(iary+0) = &*(iary) = iary」となる => 「(ポインタ)値」なので、関数の引数や、返り値に使う事ができる <= 間接参照(*)を利用して、配列の要素を、関数の呼び出し側と呼び出される側で共有できる !!! 配列は、「値の並び」に対応した「値」を表現している !!! 配列がもつ「値」を変更する場合は、 !!! 配列の要素のすべての変更する場合より、 !!! 少ない個数(多くの場合は一つの)要素を変更する場合が多い !!! cf. DataBase の表 !!! => 配列の表す値を変更する場合は、(全体コピーせず)一部を変更すると効率が良い # ポインタ値と、配列の関係 # ポインタ値が、配列の一部を参照している場合 動的なメモリ管理 cf. 変数宣言(配列宣言を含む..) => プログラム内に、明示的に、そのサイズを指定する => 表現したいデータサイズが、予めわかっていないと、宣言(プログラム作成)ができない => プログラムの実行時も、その固定されたサイズしか利用してはいけない !!! そのサイズを超える要素を(実行時に..)参照すると、いろいろなトラブルの原因になる !!! <= 間接参照を利用する場合は、「宣言していない領域が参照できてしまう..(セキュリティホールの遠因になる) 実行時に、領域を動的(必要なサイズをその状況に応じて)に確保する malloc/calloc で動的に領域を確保 / free で利用済み領域を開放 利点: 領域を実行時に決める事できるので、柔軟性(必要なサイズだけとれば、効率性)がよくなる 欠点: ポインター変数(ポインターへの理解)が必要 free を忘れないようにする [2019/12/20] ファイル I/O C 言語で記述されたプログラムで、「ファイル」を扱いたい # C 言語そのものには、ファイルを扱う機能はない # <= ファイルを扱う「標準」ライブラリがあり、それを呼び出す # # ファイルを扱うライブラリの API を学ぶ !!! 「ファイル」<= 何等かの情報をまとめて(恒久的に..)保存してくれるもの !!! => OS によって、細かい部分が異なる !!! <= OS の違いによる、扱いの違いは、基本、ライブラリが吸収する !!! => どの OS でも、同じ形で、「(本来は異なる)ファイル」が扱える !!! <ポイント> !!! ライブラリを利用して、OS に依存しないファイル処理をできるようにする !!! ライブラリの概念によって !!! 「『異なる』対象」を「『共通の』利用」をする方法が提供される C 言語で作成するプログラム内では、 ファイルポインタを入手し、そのファイルポインタを指定して、操作を行う fprintf は printf のファイルポインター利用版で、 最初の引数にファイルポインターを指定する以外は、printf と同じ fscanf も同様 以下、 getchar, putchar, (gets), puts に対して、fgetc, fputc, fgets, fputs 等がある ファイルポインタは、fopen を利用して、(ファイルを開くと同時に..) その返り値である ファイルポインタを得る事ができる 利用が済んだファイルは、fclose を用いて、ファイルポインターを指定して、閉じる。 fclose => 書き込みに関して、ある程度、やってくれる(完全ではない) => ファイルへの書き込みを完全にするには、きちんと shutdown する必要がある !!! scanf は危険 ( <= キーボードから人間が入力する場合が多く、人間は誤って入力をしてしまう可能性がある ) !!! fscanf は (指定するファイルポインタがファイルへのファイルポインタであれば..) !!! (ファイルの中身は適切だと仮定したうえで..) 安全に入力できる