第 8 回 関数 (1) 関数の作成
数学ライブラリの関数 以下のような数学関数は, 数学ライブラリに関数として登録されている <math.h> をインクルードすれば使用できる コンパイルするときには, lm を付ける double exp(double x) ee xx double log(double x) llllll ee xx double pow(double x, double y) xx yy double sqrt(double x) xx double cos(double x) cos xx double acos(double x) arccos xx double fabs(double x) 絶対値 xx double floor(double x) 床関数切り捨て : xxを超えない最大の整数 : xx double ceil(double x) 天井関数切り上げ : xx 以上の最小の整数 : xx double round(double x) 四捨五入 : xx に最も近い整数
数学関数の使用 ( 呼び出し ) #include <stdio.h> #include <math.h> double a, b; scanf("%lf", &a); b = cos(a); printf("%f n", b);
引数を 1 つだけもつ関数の定義 例 : double square(double x) x の 2 乗 戻り値の型 (return value) 関数名 引数の型 (arguments) double square(double x) double y; y = x * x; return y; 仮引数 (formal arguments) ( パラメータ ) (parameters) 呼び出し元に関数値 ( 戻り値 ) を戻す (return a value) double a,b; a = 2.3; b=square(a); printf("%f n", b); 関数を呼び出す(call a function) (a の値は実引数 ) (actual arguments)
引数を 2 つもつ関数の定義 例 : double distance(double x, double y) (0, 0) と (x, y) の距離 double distance(double x, double y) double z; z = sqrt(square(x)+square(y)); return z; square は 1 つ前のスライドで自分で定義した関数 sqrt は math.h で定義されている関数 double theta; scanf("%lf", &theta); printf("%f n", distance(cos(theta),sin(theta));
引数や戻り値のない 関数 の定義 #include <stdio.h> 戻り値なし 引数なし void greeting(void) printf("hello! n"); 関数 (function) 手続き (procedure) 戻り値は int 引数なし greeting(); int 型の 0 を OS に戻してプログラムを終了
後方参照の原則 (backward reference) プロトタイプ宣言で前方参照が可能になる (prototype proclamation) (forward reference) int add(int a, int b) int c; c=a+b; return c; 後方参照 int x=1, y=2, z; z=add(x,y); printf("%d n", z); プロトタイプ宣言 int add(int a, int b); int x=1, y=2, z; z=add(x,y); printf("%d n", z); 前方参照 int add(int a, int b) int c; c=a+b; return c;
ローカル変数 ( 局所変数 ) のスコープ (local variable) (scope) int add(int a, int b) int c; c=a+b; return c; 値がコピー されて戻される 異なる変数に 値がコピー される int a, b=2, c=3; a=add(b,c); printf("%d n", a); スコープ : 有効範囲 a, b, c のスコープ ( 局所的 ) a, b, c: ローカル変数 (local variable) これらの a, b, c は名前が同じだが異なる変数 a, b, c: ローカル変数 a, b, c のスコープ ( 局所的 )
グローバル変数 ( 大域変数 ) のスコープ (global variable) double dol2yen(double d); double rate = 116.2; double mydol = 26.0, myyen; myyen = dol2yen(mydol); printf("%f n", myyen); double dol2yen(double d) double yen; yen = d * rate; return yen; rate: グローバル変数 rate のスコープ ( 大域的 ) この rate は大域変数 ( 期待どおり動く )
ローカル変数のライフタイム (lifetime) int countup(void); ライフタイム (lifetime): 生存期間 int one,two; one=countup(); two=countup(); printf("%d n", two); countup count=0 count=1 count のライフタイム ( 局所的 ) countup count=0 count=1 time count のライフタイム ( 局所的 ) int countup(void) int count = 0; count = count + 1; return count; 間違い count : ローカル変数 ローカル変数は, スコープもライフタイムも局所的
グローバル変数のライフタイム int countup(void); int count = 0; 正しい count : グローバル変数 int one,two; one=countup(); two=countup(); printf("%d n", two); countup countup count=0 count=1 count=1 count=2 count のライフタイム : 大域的 ( 永続的 ) time int countup(void) count=count+1; return count; 正しい グローバル変数は, スコープもライフタイムも大域的
擬似乱数を発生する関数 (1/2) (pseud-random number) rand 関数 int rand(void) rand 関数は,0 から RAND_MAX までを範囲とする int 型の擬似乱数を発生して返す. RAND_MAX =2147483647 (=2 31-1) 使用例 : int n = rand(); rand 関数は前回生成した擬似乱数をグローバル変数 r に記憶し, 適当な数 A を用いて r = (A*r)%(RAND_MAX+1); のような処理で新たな擬似乱数を作る
擬似乱数を発生する関数 (2/2) srand 関数 void srand(unsigned seed) srand 関数は, 擬似乱数列の開始点 (seed) をセットする. rand 関数で擬似乱数系列を発生させる前に 1 度だけ実行する. 引数には time 関数を使って現在時刻 ( 秒 ) を与えることが多い. 使用例 :#include <stdlib.h> #include <time.h> srand((unsigned)time(null)); int r1 = rand(); int r2 = rand();
参考 スタティック変数 (static variable) int countup(void); int one,two; one=countup(); two=countup(); printf("%d n", two); スタティック変数は, 過去の記憶を持つ countup countup count=0 count=1 count=1 count=2 count のライフタイム ( 永続的 ) time int countup(void) static int count = 0; count=count+1; return count; count : スタティック変数 宣言と同時に初期値を指定しておくと, はじめて関数が呼び出されたときだけ count は初期値に初期化される count のスコープ ( 局所的 ) スタティック変数は, スコープは局所的, ライフタイムは永続的