C言語 第11講 生物機能制御学講座 濱田 農学部7号館209室 1 本日の講義内容 • おさらい 関数など テキスト Lesson 8 • 関数つづき テキスト Lesson 8 • プログラムの作成 • アンケート 2 アンケート結果 質問および要望 1.「引数」の意味が良くわからない 2.「戻り値」の意味が良くわからない 3.第11講の関数の内容について わかった(特に問題ない) 13名 むずかしい 7名 ノーコメント 3 関数 プログラムが、以下の構成の場合! 1) 同じ内容のブロックを何度も 記述しないといけない 2) 1つのブロックが冗長 すっきりしたプログラムを作成したいですね! すっきりしたプログラムは、デバッグ効率を 格段に向上させ、メンテナンスも楽になります! main() { Block_A ・・・・ Block_A Block_A ・・・・ Block_A } 1)や2)のブロックをmain()以外の箇所に記載(関数)し、main() の実行したい当該箇所とリンクする! コーディングがすっきりします 4 関数のしくみ main() { A1; ・・・ ・・・・ A1; ・・・ ・・・・ A1; ・・・ } F_A() 詳述 処理の呼び出し { A1; ・・・ AN; } AN; AN; AN; restructure 何度も A1; ・・・ AN;がある (A1;・・・AN;はBlock!) F_A() : 関数! 実は、main()も関数! main() { 粗筋 F_A(); ・・・・ F_A(); ・・・・ F_A(); 次の処理へ } 5 関数の定義 構文 <#include文からmain()の間に記載> 戻り値の型 関数名(仮引数リスト) z f x, y { 変数宣言; int f(int x, int y) (例1) intに限りません { 文; int z; return 式or値; z = x + y; } return z; ← 戻り値 } void: 該当なし! 戻り値なし;引数なし voidは省略可能! void output(void) (例2) { printf(“関数名output!\n”); } 戻り値なしの場合、return 文を省略可 6 関数の仕様パターン 構文 <#include文からmain()の間に記載> 戻り値の型 関数名(仮引数リスト) { 変数宣言; # 戻り値 引数リスト 文; 1 ×(void) ×(void) return 式or値; 2 ×(void) ○(変数宣言) } 3 4 ○(return) ×(void) ○(return) ○(変数宣言) 7 関数のよびだし 1 構文 1) 関数の戻り値が void 関数名(実引数リスト); 2) 関数の戻り値が 値 変数 = 関数名(実引数リスト); 関数は何度もよびだせる! voidの実引数は空欄にする output関数定義部 void output(void) { printf(“output!\n”); } void main() { output(); output(); 関数よびだし } 関数を呼び出すと、定義しておいた処理がまとめて行なわれる8 関数のよびだし 2 void output(void) { printf(“output!\n”); } 関数定義部 2) 関数の戻り値が 値 void ope1(void) 変数 = 関数名(実引数リスト); { output(); 関数よびだし 関数はmain()中だけでなく、 } 任意の関数中からもよびだせる! main() (カスケードできる) { 関数よびだし ope1(); 全てのよびだしはmain()に帰着 } 構文 1) 関数の戻り値が void 関数名(実引数リスト); 関数はよびだし元よりも上記すること! 9 関数の利用(練習) 問題1 関数を用いて、以下の出力を行うプログラム を開発してください。関数名は、任意です。 「関数のよびだし1または2」を参考に以下のアルゴ リズムに従って作成してください。。。 <アルゴリズム> 1 main()にて任意名の関数()をよびだす 2 1の関数内にてprintfを利用して出力する 仮引数および戻り値 voidの関数を用いる % a.out 2値を入力してください。 % 10 関数の利用 問題1 問題1のプログラム例 (主要部のみ) void output(void) output関数定義部 { printf(“2値を入力してください。\n”); } void main() { output(); } 関数よびだし % a.out 2値を入力してください。 % 戻り値なし・引数なしのケース 11 関数の引数 1 (変数) 構文 戻り値の型 関数名(仮引数リスト) void buy(int z) (例) intに限りません { printf(“%d万円です\n”,z); } main() { int x; printf(“いくら?\n”); x = 500; buy(x); /*実引数:変数*/ buy(300); /*実引数:値*/ } 引数は、関数のよびだ し元から関数内に情報 (値)を渡す。 関数はその情報に応じ た処理を行う。 x:実引数; z:仮引数; xとzの型は一致すること! 仮引数初期値は実引数の値 % a.out いくら? 500万円です 300万円です 12 関数の引数 2 (変数) 構文 戻り値の型 関数名(仮引数リスト) void buy(int a, int b) (例) intに限りません { printf(“%d万円と”,a); printf(“%d万円です\n”,b); } main() { int x; printf(“いくら?\n”); x = 100; buy(x,200); /*実引数:変数*/ } 関数には複数の引数を 渡すことができる。 引数リストの順に値が 代入される。 実引数と仮引数は対応 仮引数 a b 実引数 x 200 % a.out いくら? 100万円と200万円です13 関数の引数 3 (なし) 構文 戻り値の型 関数名(仮引数リスト) void output(void) (例) { printf(“C言語大好き\n”); } main() { int x; output(); /*実引数:なし*/ } プログラムを断片化する と、プログラムが理解し やすくなる。引数のない 関数を用いて、プログラ ムを分散させよう。 戻り値および引数の型 voidは、省略可能。 % a.out C言語大好き 注意事項:C言語は、基本的に実引数の値の更新を許さない!14 残念ながら、引数は情報を流すだけ(配列は例外)。 戻り値 構文 1) 関数の戻り値が void 関数名(引数リスト); 2) 関数の戻り値が 値 変数 = 関数名(引数リスト); 関数内の計算結果(戻り値)は、 1つだけ、return 文でよびだし元 に返還される。 戻り値と受け側変数の型が一致し なくてはならない(ここではint)。 z f x, y int f(int x, int y) { intに限りません int z; z = x + y; return z; /*戻り値z*/ } 関数定義部 main() { int a,b,c; a = 4; b = 2; c = f(a,b); 関数よびだし } 15 関数の利用(練習) 問題2 入力された任意の2つの倍精度浮動小数の大 きい数と小さい数を判断する判別関数を作成し、大小 関係を出力するプログラムを作成してください。判別 関数の名前は任意です。 <アルゴリズム> 1 main()で2つの倍精度浮動小数を入力させる。 2 2つの数を判別関数に渡し、大小関係を検討し、関 数内で、大小関係を出力(printf)する。 判別関数は、引数あり戻り値なしの関数を用いる 16 関数の利用 問題2 問題2のプログラム例 (主要部のみ) void hanbetsu(double x, double y) { if (x>y) { printf(“%lf > %lf\n”,x,y); else { printf(“%lf > %lf\n”,y,x); } main() { double a,b; printf(“a=”); scanf(“%lf”,&a); printf(“b=”); scanf(“%lf”,&b); hanbetsu(a,b); } } % a.out a=11.22 b=12.33 12.33 > 11.22 } 引数あり・戻り値なしのケース 17 関数の利用(練習) 問題3 問題2のプログラムに、倍精度浮動小数2値 の四則演算を行う演算関数を加え、以下のアルゴリ ズムに従って作成してください。関数名は、任意です。 <アルゴリズム> 1 main()にて任意の2値を入力させる(問題2で完 了)。 2 四則演算を別々に行う4つの関数を作成する。 3 main()にて関数の戻り値(四則演算結果)を出力 する。 演算関数は、引数あり戻り値ありの関数を用いる 18 関数の利用 問題3 問題3のプログラム例 (主要部のみかつ和算のみ) double wa(double x, double y) { return x + y; } /* 差・積・除算の関数は割愛 */ void main() { double a,b,z; printf("a="); scanf("%lf",&a); printf("b="); scanf("%lf",&b); z =wa(a,b); printf("a + b = %lf\n",z); /* 差・積・除算の関数よびだしは割愛 */ } % a.out a=1.1 b=0.11 a + b = 1.21 引数あり・戻り値ありのケース 19 関数の引数 4 (一次元配列) 構文 戻り値の型 関数名(仮引数リスト) #define MAX 2 void output(int t[MAX]) (例) { 仮引数: int i; 配列名[要素数] for(i=0;i<MAX;i++){ printf(“t[%d]=%d\n”,i,t[i]);} } main() 実引数: { 配列名 int a[MAX]; a[0]=0; a[1]=1; output(a); } /*実引数:配列*/ 変数と同様、 配列も引数に 適用可能! 要素数の設定 にはマクロを! % a.out t[0]=0 t[1]=1 20 関数の引数 5 (二次元配列) 構文 戻り値の型 関数名(仮引数リスト) void output(int t[1][2]) (例) { 仮引数:配列名[要素数] [要素数] int i; for(i=0;i<2;i++){ printf(“t[0][%d]=%d\n”, i,t[0][i]);} } main() 実引数: { 配列名 int a[1][2]; a[0][0]=0; a[0][1]=1; output(a); } /*実引数:配列*/ 二次元配列も 一次元配列と 同様! % a.out t[0][0]=0 t[1][1]=1 21 関数の引数 6 (配列:値更新1) 構文 戻り値の型 関数名(仮引数リスト) 関数に渡された配列 は、関数の中で実引 数の更新可能! (変数はダメ!!) void vector(int t[2]) (例) { t[0]=3; t[1]=6; /*値の更新*/ } main() % a.out { a[0]=0 a[1]=1 int a[2]; *a[0]=3 *a[1]=6 a[0]=0; a[1]=1; printf(“a[0]=%d a[1]=%d\n”,a[0],a[1]); vector(a); printf(“*a[0]=%d *a[1]=%d\n”,a[0],a[1]); } 22 関数の引数 6 (配列:値更新2) 構文 戻り値の型 関数名(仮引数リスト) 仮引数リストで、変 更したくない引数に (例) constを添付すると、 実引数の変更が不 可となる! void vector(const int t[2]) { t[0]=3; t[1]=6; /*値の更新*/ } % a.out or Error! main() a[0]=0 a[1]=1 { *a[0]=0 *a[1]=1 int a[2]; a[0]=0; a[1]=1; printf(“a[0]=%d a[1]=%d\n”,a[0],a[1]); vector(a); printf(“*a[0]=%d *a[1]=%d\n”,a[0],a[1]); 23 } 変数とスコープ1 #include <stdio.h> int a; void func(void) { int b; 変数 bの値が ・・・・・・ 保障される範囲 } void main() { int c 変数 cの値が ・・・・・・ 保障される範囲 } 変数 aの値はプログラ ム全域で保障される 範囲:スコープ 変数 変数種類 a b C グローバル変数 ローカル変数 ローカル変数 異なる関数内のローカル変数は 仮引数名を含めて、名前が重複 してもよい。異なる変数である。 24 変数とスコープ2 #include <stdio.h> int a; void func(void) { ローカル変数 int a; aの値が保障 a = 1; される範囲 } void main() { a = 0; グローバル変数 ・・・・・・ aの値が保障 } される範囲 変数種類 値 グローバル変数 a ローカル変数 a 0 1 変数値を更新するとき! ローカル変数で宣言されている場合 は、ローカル変数を更新! 否は、グローバル変数を更新 グローバル変数とローカル変数 は同じ名前にしてもよい。が、 混乱を招くので避けよう! 25 変数とスコープ3 変数の種類 記憶クラス グローバル変数 (大域変数) ローカル変数 (局所変数) 記憶(値)保存期間 プログラム起動時から終了まで static プログラム起動時から終了まで auto 宣言されてから関数終了まで ローカル変数 static宣言の構文 static int a; /*例*/ ローカル変数は関数がよびだされる度、変数や配列が 準備され、関数終了次第、廃棄(値は消滅)される。 一方、staticローカル変数は、値が保持される! 26 関数の利用(練習) 問題4 配列と関数を用いて、任意個数の数列の 合計と平均を算出するプログラムを開発してくだ さい。 <アルゴリズム> 1 main()にて任意個数の数列を入力し、配列に 格納する。 2 配列を合計用関数と平均用関数に渡す。 3 関数で合計と平均を算出し、計算結果をmain() に戻す。 4 main()にて関数の戻り値(合計と平均)を出力 する。 演算関数は、引数あり戻り値ありの関数を用いる 27 関数の利用(練習) 問題5 任意の関数を用いて、前作の直線回帰の プログラムをすっきりと再構築しなおしてください。 <アルゴリズム> 1 関数を用いて、入力・計算・出力部に分割 2 さらに各関数を再分割(平均・和算など) % % % % % cp 元file名 新file名 ← file複製命令 lp file名 ← file印刷命令 a.out < infile名 ← file入力命令 a.out > outfile名 ← file出力命令 a.out < infile名 > outfile名 28 次回の予定 ○ 次回 関数つづき おさらい (テキスト:Lesson8~) 29 おわりに • さて、問題です。 1.ローカル変数とグローバル変数って何? 2.仮引数の配列は関数内で実引数を 更新できる? 3.スコープって何? 3.その他、質問など 30
© Copyright 2024 ExpyDoc