Transcript int n
オブジェクト指向言語 オブジェクト指向言語演習 第05回 C言語の基礎 関数 スケジュール(C言語) 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 受講ガイダンスとプログラム開発基礎 Linuxの使い方と簡単なC言語プログラムの作成,実行 C言語 変数と式 (2004/10/4) C言語 制御と流れ (2004/10/4) C言語 変数と式(復習) (2004/10/18) C言語 制御と流れ(復習) (2004/10/18) C言語 関数 (2004/10/25) C言語 配列 (2004/10/25) C言語 文字列の表現 (2004/11/1) C言語 ポインタ (2004/11/1) C言語 構造体とユーザ定義型 (2004/11/8) C言語 ファイル (2004/11/8) 中間試験 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 2 出席確認 出席確認WebPage http://www.iis.it-hiroshima.ac.jp/att/ 講義用WebPage http://www.iis.it-hiroshima.ac.jp/~nagasaka/ lect/oo/2004/ 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 3 プログラミング言語 C 関数 ( Function ) カプセル化構造-関数 関数とは ある処理(仕事)をするブロック(かたまり) 入力(複数) 処理 出力(1つ) 値 値 処理 出力 値 入力 関数の使用 関数の宣言 関数の呼び出し 関数の定義 関数 たとえば、与えられた数の2乗を計算す る簡単な関数f(x)の例 5 入力 27.Sep.2004 25 f(x) Object Oriented Language - Y.Nagasaka: [email protected] 出力 5 関数の定義方法 一般的な関数の定義は以下の通りである。 入力1 関数の型名 関数名( 引数名1の型名 引数1, .... , 引数名nの型名 引数n) { 入力n 内部変数定義; 文1; 文2; ・・・ } 27.Sep.2004 return 関数値; 関数名 引数1 関数 関数値 引数n 引数とは関数に与えるパラメータ のこと 関数の出力値 return値とも呼ぶ Object Oriented Language - Y.Nagasaka: [email protected] 6 整数の正のべき乗を計算する関数の例(1) 関数名をpowint、y=xpを計算するとする。関数の 入力はx,p(整数型)であり、関数からの出力値はy(整 数型)となる。 int powint (int x, int p) { yは関数powint内 だけで有効 int y = 1; while (p-- > 0) { y *= x; } pの値を次々に減らしていき、 0になるまで繰り返す。すな わち、このループはp回繰り 返される。 return y; } 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 7 整数の正のべき乗を計算する関数の例(2) 作成されたpowintを使う。 #include <stdio.h> int powint(int x, int p); int main(void){ int i, j; for (i=0; i <= 10; i++) { j=powint(2, i); printf(“%d\t%d\n”, i, j); } return 0; } 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] プロトタイプ宣言 プログラム内で使用 される関数の名前や 引数の順序、型など を記述する。 関数呼び出し powint関数を呼び出 す。ここでは、xとし て2が使用されている ので2のi乗が計算さ れ、それがjに代入す る。 8 関数を含むプログラムの構造 プログラムの一般形式 #include <stdio.h> #include <ヘッダファイル名> プロトタイプ宣言 int main(void){ 変数宣言; メインプログラム return 0; } 関数型 } 27.Sep.2004 関数名(仮引数) { 関数内で有効な変数の宣言; 関数のプログラム; return 結果の値; ヘッダファイルを読み込む。 このヘッダファイルにはプ ロトタイプ宣言や定数定義 が書かれている。 stdio.hはシステムの標準関 数のプロトタイプ宣言など が記述されており、 /usr/include/stdio.hに 入っている。 #include “ファイル名” 任意のディレクトリにある ファイルを読み込むことが できる。 Object Oriented Language - Y.Nagasaka: [email protected] 9 関数の呼出し手順(1) 組み合わせを求める関数combiを作成する。 組み合わせは、nCr=n!/(r! * (n-r)!)で定義される。 int combi ( int n, int r) { int i, nk=1, rk=1, nr=1; for (i = 1; i <= n; i++) { nk *= i; } 局所変数(local variable) i, nk, rk, nrは関数 combi内のみで利用可能 1.n!を求める。 for (i = 1; i <= r; i++) { rk *= i; } 2.r!を求める。 for (i = 1; i <= (n-r); i++) { nr *= i; } 3.(n-r)!を求め る。 return nk / (rk * nr ); } 27.Sep.2004 4.nCrを計算す Object Oriented Language - Y.Nagasaka: [email protected] 10 関数の呼出し手順(2) 関数を呼び出す側のプログラム #include <stdio.h> int combi(int , int); /*プロトタイプ宣言では引数名を省略可能*/ int main(void){ int t, m; for (t=0; t <= 5; t++) { for (m=0; m <= t; m++){ printf(“%dC%d=%d\t”, t, m, combi(t,m)); } } printf(“\n”); return 0; } combi(m, t) m, tの値を 呼び出し n, rに受け渡す int combi(int n, int r) 27.Sep.2004 呼び出し側の引数(m,t)を実 引数と呼び、 関数側の引数(n,r)を仮引数 と呼ぶ。 Object Oriented Language - Y.Nagasaka: [email protected] 11 関数の呼出し手順(3) 関数呼び出しの手順 1. 2. 3. 4. 5. 値渡し(called by value) 関数呼び出しが行われる 実引数の値を仮引数にコピー その関数の定義部分を実行する 計算結果をその関数の値として返す 関数を呼び出したプログラムへ制御を戻す 関数の呼び出しのときに、実引数の値を仮引数にコピーして渡 す方法 C言語の場合、通常の呼び出し方法が値渡しである。 参照渡し(called by reference) 27.Sep.2004 関数の呼び出しのときに、実変数のメモリアドレスを仮引数に コピーして渡す方法 scanfの時の変数の前の「&」、ポインタ(次週以降に説明) Object Oriented Language - Y.Nagasaka: [email protected] 12 関数の中から別の関数を呼び出す(1) combi関数の中で同じような処理が3回あった。 int combi ( int n, int r) { int i, nk=1, rk=1, nr=1; for (i = 1; i <= n; i++) { nk *= i; } for (i = 1; i <= r; i++) { rk *= i; } for (i = 1; i <= (n-r); i++) { nr *= i; } return nk / (rk * nr ); } 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 13 関数の中から別の関数を呼び出す(2) 階乗を計算する関数factを定義して利用する。 #include <stdio.h> int fact(int); int combi(int, int); int main(void){ メインプログラム; } /*プロトタイプ宣言*/ /*プロトタイプ宣言*/ int fact (int n){ int i, fact=1; for (i = 1; i <= n; i++) { fact *= i; } return fact; } int combi ( int n, int r) { return fact(n) / (fact(r) * fact(n-r) ); } 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 14 外部変数と局所変数 外部変数(global variable) 関数の外部(外側)で宣言された変数 すべての関数から参照可能 どの関数から参照しても、その変数の中身は同一 局所変数(local variable) 関数の内部(内側)で宣言された変数 それぞれの関数の内部でしか有効ではない 関数の外側からは参照できない 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 15 外部変数と局所変数の例 #include <stdio.h> void vartest(int a); int g = 100; int main(void) { 外部変数 int a, b, c; g ← 100 a = 1; b = 2; c = 3; 局所変数(main関数) printf("main : (g,a,b,c) = (%4d,%4d,%4d,%4d)\n", a ← 1 g, a, b, c); b ← 2 vartest(a); c ← 3 printf("main : (g,a,b,c) = (%4d,%4d,%4d,%4d)\n", g, a, b, c); } 局所変数(vartest関数) void vartest(int a) { a ← 関数の引数 a int b, c; b ← 20 b = 20; c ← ?(宣言のみ) printf("vartest: (g,a,b,c) = (%4d,%4d,%4d,%4d)\n", g, a, b, c); return; 外部変数gは関数内からも } 参照できる 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 16 自動変数とstatic変数 自動変数 関数の仮引数や局所変数のように、関数が呼ばれる毎にそ の変数に対するメモリ領域を確保する。 autoという記憶クラス指定子があるが、関数内で何も指定 しなければ、auto付であると認識される。 static変数 プログラム起動時に1度だけ、その変数に対するメモリ領 域が確保される。 関数が何度も呼ばれる場合、その変数は同じ領域(同じ 値)を使用することになる。すなわち、他の関数から参照 できない外部変数のようなものである。 書き方: static 変数型名 変数名; static int time; 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 17 変数の通用範囲(スコープ) (1) 自動的な変数の通用範囲 自動的な変数には、関数の仮引数、auto変数がある 関数の仮引数の通用範囲は、その関数のブロック内だけで ある。 <<プログラムの形式5.8>> (p.200) auto変数の通用範囲は、その変数が定義されたブロック内 だけである。 <<プログラムの形式5.10>> (p.200) 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 18 戻り値の無い関数、引数の無い関数 戻り値の無い関数(void型関数) 関数の結果から戻り値を必要としない場合 void 関数名(引数型 引数,...){ return; } p.168参照 引数の無い関数 引数の無い関数の場合 関数型 関数名(void){ ............... } p.180参照 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 19 変数の通用範囲(スコープ) (2) 静的な変数の通用範囲 静的な変数には、 static変数、外部変数がある。 static変数の通用範囲はその変数が定義されたブロック内 だけである。 <<プログラムの形式5.11>> (p.201) 外部変数の通用範囲は、その定義の直後からそのコンパイ ル単位(通常はファイル)である。ただし、extern宣言す れば、他のコンパイル単位からも参照可能。 <<プログラムの形式5.12>> (p.202) 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 20 課題1 二つの整数変数の引数の和を計算して結果を戻す関 数plusを作成し、それを利用して以下の実行結果に なるようにしなさい(ファイルoo07-1.c)。 int plus( int a, int b); % ./oo07-1 Input two integer numbers 4 5 4+5=9 % 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 21 課題2(1) 階乗を求める関数factとべき乗を求める関数powint を利用して、n!/xnを求める関数pow_fact関数を作 成しなさい(ファイルoo07-2.c)。 ただし、pow_fact関数は引数に整数値をとるが、戻 り値は実数となることに注意しなさい。 float pow_fact(int x, int n); /*プロトタイプ宣言*/ factとpowintはそれぞれ教科書のリスト5.16 (p.185)とリスト5.2 (p.164)を参照しなさい。 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 22 課題2(2) 実行例 関数pow_factを作成しな さい。 mainプログラムの例 % ./oo07-2 Input number 5 1 2 3 4 5 % 1.000000000 0.500000000 0.222222224 0.093750000 0.038400002 #include <stdio.h> int powint(int, int); int fact(int); float pow_fact(int, int); int main(void) { int i, n; printf("Input number\n"); scanf("%d",&n); for (i=1; i <= n; i++) { printf("%10d %20.9f\n",i, pow_fact(i, i)); } } 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 23 コンパイルと実行 まずはじめに 作業ディレクトリの作成 一度実行すればよい % mkdir ~/wrk/ % mkdir ~/wrk/oo/ 次に 作業ディレクトリへの移動 プログラミング コンパイル・リンク 実行 % cd ~/wrk/oo % vi lect01-1.c % gcc -o lect01-1 lect01-1.c % ./lect01-1 * C言語プログラムのファイル名は、.c でなければならない 27.Sep.2004 Object Oriented Language - Y.Nagasaka: [email protected] 24