情報基礎演習B 後半第5回 担当 岩村 TA 谷本君 前回の復習1 構造体 新しい変数の型を定義する メンバの参照 ドットを用いる 変数名.メンバ 前回の復習2 ファイルポインタの宣言 FILE *fp; ファイルのオープン fp=fopen(“ファイル名”, “モード”); モード r: 読み込み(ファイルがなければエラー) w: 書き込み(既にファイルがあれば破棄して上書き) a: 追加(ファイルがあれば。なければwと同じ) ファイルのクローズ fclose(fp); 先週の課題 任意の人数の名前、身長、体重をファイルか ら読み込み、BMIを計算して出力するプログ ラムを作成しなさい 名前、身長、体重、BMIを扱う構造体を使う データファイルは用意してあるものを使う データファイルの構造 人数、(1人目の)名前、身長、体重、 (2人目の)名前、 身長、体重… ただし身長の単位はcm、体重はkg 課題の解答 後半の予定 1. 2. 3. 4. 5. 関数 ポインタ(前半) ポインタ(後半) & メモリの動的確保 構造体 & ファイルの入出力 プリプロセッサ & 復習+α (おまけ)文字列処理 & コマンドライン引数の 処理 プリプロセッサ コンパイル前にプログラムを書き換える処理 例) #include <stdio.h> #define N 50 ファイルの挿入(#include) 関数は使う前に定義が必要 /* stdio.h */ 修正後のプログラム printfの定義… fprintfの定義… scanfの定義… fscanfの定義… /* stdio.h */ #include<stdio.h> int main(void){ printf(“hello!!\n"); return(0); } コンパイル前に プログラムを修正 printfの定義… fprintfの定義… scanfの定義… fscanfの定義… int main(void){ printf(“hello!!\n"); return(0); } マクロ定義 (#define) 1. 文字列の置き換え 2. #define N 50 マクロの定義 #define wa(a,b) a+b 副作用があるので注意が必要 文字列の置き換え コンパイル前に文字列を置き換える 書式 #define 置き換える文字列 置き換えられる文字列 例 #define N 50 #define FILENAME “data.txt” 効能 後で数値やファイル名などを変えたいとき、一括し て変えられる マクロの定義 コンパイル前に文字列を置き換えて、関数の ような処理を行う 例) #define wa(a,b) a+b printf("wa(x,y) = %f\n",wa(x,y)); 文字列の置き換えによって wa(x,y)x+y を実現 マクロの定義と関数の違い 関数との違い 変数の型がない 単にソースコードを変更しただけなので 余計な処理時間がかからない 普通関数を呼び出すと多少時間がかかる マクロは単にソースコードを変更しただけ 注意しないと意図した動作をしない場合がある (副作用) マクロの定義の副作用 プログラム #define kake(a,b) a*b printf("wa(x,y) = %f\n",kake(x,y+10)); マクロの展開 括弧がない! kake(x,y+10)x*y+10 ≠x*(y+10) これまでの復習+α ポインタについて アドレスを扱う変数 関数の呼び出し方法の違い 1. 値を渡す 2. アドレスを渡す(配列を渡す) 配列の先頭のアドレスを関数に渡せば、 配列を関数に渡したことになる ポインタ アドレスを扱う変数 具体的には、変数が格納されているメモリの先頭 番地を記憶する 動的な配列の確保(malloc) ポインタを用意すれば、mallocが配列を確保し てくれる 関数の先頭でなくてもよい 配列の大きさはプログラムの実行後に決定可能 一方、配列だと… 関数の先頭でないと宣言できない 配列の大きさはコンパイル時に決定(定数のみ) 配列でよくある間違い int n; int a[n]; nは変数! これはmallocでしか実現できない 動的な配列の確保(malloc)の動作 動的でない配列(int a[3]) a自体がポインタみたいなもの 関数への値の渡し方 関数wa main関数 a,bの値をx,yにコピー int wa(int x, int y) { int z; … z=x+y; sum=wa(a, b); return z; … zの値をsumにコピー } 関数wa(参照渡しversion) void wa(int *z, int x, int y) { *z=x+y; } sumの中身を変更 main関数 … wa(&sum, a, b); … sumのアドレスをzにコピー 配列を関数へ渡す方法 mallocで配列を確保した場合 int wa_all(int n, int *a) { int i, t=0; for (i=0; i<n; i++) { t += a[i]; } return(t); } int *a, n=5, total; a = (int *)malloc(sizeof(int)*n); … total = wa_all(n, a); … free(a); int a[5]で配列を確保した場合 int wa_all(int n, int a[]) { int i, t=0; for (i=0; i<n; i++) { t += a[i]; } return(t); } int a[5], n=5, total; … total = wa_all(n, a); …
© Copyright 2024 ExpyDoc