物理情報処理基礎実習II 第12回

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言語たる部分「ポインタ」をさらっと。
深入りすると大変なことになるので、さらっと!
それに加えて、
ファイルからの入力、ファイルへの出力のやり方を。