http://www.phys.ynu.ac.jp/labs/cosmic/shibata/jisshu/ 物理情報処理基礎実習II 第12回 関数 (原 [email protected]) 柴田 [email protected] 石川 [email protected] 課題10-解答例(平均値,最大,最小) aplsrvky01% cat kadai10.c #include <stdio.h> main() { int i,n; double x,sumx=0.,average; double xmax=-100.,xmin=100.; printf("How many data ? "); scanf("%d",&n); for(i=0;i<n;i++){ printf("Input data [%d] : ",i+1); scanf("%lf",&x); sumx=sumx+x; ※合計算出 if(x<xmin) xmin=x; ※最小値 if(x>xmax) xmax=x;※最大値 } average=sumx/n; ※平均算出 printf("Minimum=%#12.5g\n",xmin); printf("Maximun=%#12.5g\n",xmax); printf("Average=%#12.6g\n",average); } ◆実行例 aplsrvky01% cc kadai10.c -o kadai10 aplsrvky01% ./kadai10 How many data ? 10 Input data [1] : 1.2065 Input data [2] : 4.7500 Input data [3] : 5.7824 Input data [4] : 8.6720 Input data [5] : 6.4927 Input data [6] : 9.2760 Input data [7] : 5.8723 Input data [8] : 4.2371 Input data [9] : 5.2014 Input data [10] : 7.0012 Minimum= 1.2065 Maximun= 9.2760 Average= 5.84916 課題11aフローチャート i=0 id[]:学籍番号 pt[]:点数 i<n1 データ数nセット j=i+1 i=0 j<n i<n pt[j]>pt[ i] id[i],pt[i]入力 pt[i],pt[j]交換 id[i],id[j]交換 i++ 真→青分岐 偽→赤分岐 j++ データ数nを自動で セットする工夫も... i++ 出力/終了 i番目に残りから 最大値を見つけ てセットする。 学籍番号 も同時に 真→青分岐 偽→赤分岐 2 3 4 5 6 x x x x x x x + + + exのx=0の周りのtalor展開 e =1+ + + 1! 2! 3! 4! 5! 6! フローチャート 課題11bフローチャート p=1.0;m=1;i=1 ヘッダ出力 x=0.0 x<1.000 1 i<=6 終了 m*=i; 階乗の計算 p=p+xi/m; talor級数の 計算 e=exp(x); i++ x+=0.05 出力 次数6への依存性 をなるべく最小に §関数とは C言語に於けるプログラムとは、 main関数を大元とした関数の集合体 main関数…名前固定、自分で書く。 ライブラリ関数…システムが用意(printf、sqrt等)。 ユーザ関数…ユーザが自由に定義して書く。 今までやってきたプログラムは… main関数からライブラリ関数を呼ぶプログラム そろそろ出てきている問題点 どんどんmain関数が長くなってきている 同じ処理を何回も書くことがある ユーザ関数で、プログラムをパーツ分け! §関数の定義 文法 ※main関数と基本的には同じ 戻り値の型 関数名(引数リスト) { ※↑ 「;」不要! 中身 ※void型以外なら必ず戻り値を設定。 } ex.) 足し算する関数 sum double sum(double a, double b) { double s; s = a + b; return s; ※← sを戻り値とする } §引数と戻り値 引数 関数が参照する値(複数可能) 戻り値 関数が返す値。関数の値(複数不可) ex.) 前項の例“sum” 引数…double型のa、double型のb 戻り値…double型のs printfやscanfにも戻り値はある y = sqrt(x) ※←関数sqrtの戻り値をyに代入 printf(“%lf”,y) ※←戻り値を何にも代入しない §void型&return文 void型 ※void=空の 引数や戻り値の(必要が)無い関数もある。 → 型宣言にはvoidを使用。 ex.) void 関数名(引数リスト) ※戻り値が無い 戻り値の型 関数名(void) ※引数が無い void 関数名(void) ※戻り値も引数も無い return文 その関数の戻り値を設定する。 文法 return 戻り値; ※←戻り値は、数値を直接でも変数でも良い。 1つの関数内で何度も使って良い。 戻り値がvoid型の関数では必要ない。 §プロトタイプ宣言 プロトタイプ宣言 C言語では、変数だけでなく、関数も、 最初に使用される前に型宣言を行う必要がある。 → 最初に“とりあえず“、型宣言だけを行う。 ※中身は後で書くわけだ。 文法 戻り値の型 関数名(引数の型のリスト); またもや関数sum double sum(double, double); ex.) ライブラリ関数のプロトタイプ宣言は、 ヘッダ(stdio.hとか)の中に入っている。 §実際の書き方 一般的なプログラムの書き方 2. #include 使うシステム関数のヘッダ (ユーザ関数の)プロトタイプ宣言 3. main関数(){ 1. 5. ユーザ関数2(引数,,){ 変数 型宣言; ユーザー関数内処理; return; 型宣言; main関数内処理; 4. } ユーザ関数1(引数,,){ 変数 型宣言; ユーザー関数内処理; return; } 6. } … 注)処理の流れ §例 -I 先ほどから例に使ってる関数sumを用いる 1. 2. 3. 4. 5. 6. 7. 8. 9. #include <stdio.h> double sum(double, double); main() { double x, y, z; printf ( “input X : ”); scanf ( “%lf”, &x); printf ( “input Y : ”); scanf ( “%lf”, &y); 出力例 aplsrvky01% ./a.out input X : 1 input Y : 2 X+Y=3.000000 10. 11. 12. 13. 14. 15. 16. 17. 18. z = sum ( x, y ); printf(“X+Y=%lf\n", z); } double sum (double a, double b) { double s; s = a + b; return s; } §例 -II- 配列が引数 関数sumの引数を配列にする場合。 プロトタイプ宣言 double sum(double [ ], int); ※←“[ ]”が配列を意味 関数 double sum(double c[ ], int n) { ※↑nは配列の要素数 int i; double s = 0; for ( i=0 ; i < n ; i++ ){ s += c[i]; } return s; ※←sには配列内の数値の和が入る。 } §ローカル変数&グローバル変数 ローカル変数(いままで使ってた変数) その関数の中でだけ有効。 つまり、ローカル変数は、 関数ごとに同じものがあっても良い! グローバル変数 そのファイルの中(~.c)で、 複数の関数にまたがって有効。 文法 static 型宣言 変数名; ※関数の{}の外で宣言を行う。 変数の有効範囲(その変数が使える範囲)の話 変数の生存期間 cf. 教科書p.158~ 課題12関数(5角形の面積) 5角形ABCDEの各辺と2つの対角線の長さが以下 のように与えられている。 AB=6.0 BC=6.0 CD=7.0 DE=7.0 EA=5.0 対角線 AC=10.0 CE=10.0 5角形を3角形に分割し、5角形の面積を3角形の面 積の和として求めなさい。 ただし、 3辺の長さを引数として3角形の面積を計算する関数を作成 すること。 計算結果の出力は小数点以下2桁で表示すること。 おまけ グローバル変数は、使わないに越した事はないです。 どうしても使わないとうまく処理できない時に使おう。 goto文よりはマシですが、 下手するとプログラムが混乱します。 次回は、C言語のC言語たる部分「ポインタ」をさらっと。 深入りすると大変なことになるので、さらっと! それに加えて、 ファイルからの入力、ファイルへの出力のやり方を。
© Copyright 2024 ExpyDoc