Transcript a[2]

C言語
第10講
生物機能制御学講座 濱田
農学部7号館209室
1
本日の講義内容
• おさらい
配列
テキスト Lesson 7
• 関数
テキスト Lesson 8
• プログラムの作成
• アンケート
2
アンケート結果
質問および要望
1.「%S」の意味が良くわからない
2.プログラムの手本がほしい
3.配列の利用について
OK!つかえる
9名
ちょっと難しい
12名
レポートで使い切らない
4名
3
1次元配列
同じ型の値を複数まとめて記憶する!
1次元
配列
a[0] a[1] a[2] a[3] a[4]
Vecto
rで
す!
変数の型名:
int float double char
配列の宣言:
型名 配列名[要素数];
intの値
例
int a[5];
を5個記憶
要素数は整数固定値を設定すること
各要素の参照: a[0],a[1],……,a[4]
要素番号(添字)は0~(要素数-1)まで
4
2次元配列
同じ型の値を複数まとめて記憶する!
2次元
配列
b[0][0] b[0][1] b[0][2] b[0][3] b[0][4]
Matrix
です!
b[1][0] b[1][1] b[1][2] b[1][3] b[1][4]
変数の型名:
int float double char
配列の宣言:
型名 配列名[行要素数][列要素数];
例
float b[2][5];
floatの
値を2×5
要素数は整数固定値を設定すること
個記憶
各要素の参照: b[0][0],b[1][2] など
要素番号(添字)は0~(要素数-1)まで
5
配列の利用
① 配列要素への値の代入
配列名[添字]=式 or 値;
int a[2]; float b[3][3]; char c[4];
a[0]=x+y;
a[1]=2;
b[0][1]=x*y;
b[1][2]=5.0;
c[0]=‘A’;
c[1]=‘B’;
② 配列要素の値の出力
int a[4]; double b[4][3]; char c[3];
printf(“%d %lf”,a[0],b[1][2]);
printf(“1文字の場合は %cです”,c[2]);
printf(“配列の文字列の全ての出力は %sです”,c);
“%s”は初登
場
6
配列の利用
③ 配列要素へキーボードから値入力
int a[4]; float b[4][3]; char c[6];
scanf(“%d”,&a[0]);
/*数値入力*/
scanf(“%f”,&b[2][1]); /*数値入力*/
c[0]=getchar();
/*文字入力*/
scanf(“%s”,c);
/*文字列入力*/
“%s”です、”&”は不要
④ 注意事項
1)宣言した型と一致しない値は代入できない
ただし、intをfloatおよびdoubleへ、
floatをdoubleへの代入はできる!
2)配列の要素数を超えて利用できない!
3)配列の値を参照するときは添字に気を配ること
7
for文を利用した一次元配列操作
配列へのキーボード入力と出力(主要部のみ)
int i; int a[3];
% a.out
for(i=0;i<3;i++) { /*要素数*/
I_a[0]=9
入力
printf(“I_a[%d]=”,i);
I_a[1]=6
scanf(“%d”,&a[i]); }
I_a[2]=3
printf(“--------\n”);
-------O_a[0]=9
for(i=0;i<3;i++) { /*要素数*/
O_a[1]=6
出力
printf(“O_a[%d]=”,i);
O_a[2]=3
printf(“%d\n”,a[i]); }
添字出力
8
for文を利用した二次元配列操作
配列へのキーボード入力と出力(主要部のみ)
int i,j; float f[2][3];
for(i=0;i<2;i++) { /*行要素数*/
for(j=0;j<3;j++) { /*列要素数*/
入力
scanf(“%f”,&f[i][j]); }}
for(i=0;i<2;i++) { /*行要素数*/
for(j=0;j<3;j++) { /*列要素数*/
printf(“%f\n”,f[i][j]); }} 出力
i
0
0
0
1
1
1
for文をネストすれば、二次元配列の入出力もすっきり記述!
j
0
1
2
0
1
2
9
マクロ(#define)
数値や
文字など
の値を
代名詞
に置換
先ほどのプログラムにて
#include <stdio.h>
#define SUB 2
文末に”;”は不要
#define NUM 3
main()
{
要素数を変更
int i,j; float f[SUB][NUM];
するプログラム
for(i=0;i<SUB;i++) {
の改良は、
for(j=0;j<NUM;j++) {
#define文を
scanf(“%f”,&f[i][j]); }}
変更するだけ
ですむ(楽☆)!
for(i=0;i<SUB;i++) {
for(j=0;j<NUM;j++)
{
printf(“%f ”,f[i][j]); }}
} /* main() end. */
10
文字列と配列の関係
‘Hello’という文字列を配列に格納する!
char型の配列を宣言
char str[6];
str[0]=‘H’;
str[1]=‘e’;
1文字ずつ丁寧に
str[2]=‘l’;
配列要素に代入
str[3]=‘l’;
str[4]=‘o’;
必ず最後に’\0’を代入
str[5]=‘\0’;
文字型配列の要素数は、“文字列の長さ+1”以上必要である!
11
文字列の操作は、’\0’を利用すると便利である。
レポート課題
問題
『汎用性の高い直線回帰プログラムの開発』
5) レポート内容 (表紙:レポート名・学籍番号・氏名)
① 直線回帰を導出 (ほぼ○、コピー×)
② 決定係数を導出 (ほぼ○、コピー×)
③ 直線回帰プログラムのアルゴリズムを解説
④ 実験1と実験2の解析 (問題・単位未記載)
⑤ 決定係数などを用いて、解析結果を考察
⑥ 付記:開発した直線回帰プログラムを添付
⑦ 参考文献
(↑prgなし)
12
直線回帰のプログラムの開発
n組のデータ(xi,yi)を用いて直線回帰式 y  a  bx の
勾配 b と切片 a を最小二乗法により求めると、
b
n  x  y    x   y
n x   x 
2
2
y  b x

a
n
決定係数(相関係数の二乗)r2は
  
  
2
  x 2  n
x


2

r  b
2
  y 2  n
y

 
で与えられる。
13
Michaelis-Menten’s Eq.
基質濃度S、反応速度V、 最大生成速度Vmax、
ミカエリス定数Kmとすると
Vmax  S
V 
Km  S
両辺を逆数にすると、
1
1
Km 1
y  a b x



V
Vmax Vmax S
となる(ラインウィーバー・バークプロット )。
SとVの逆数を用いて直線回帰を施すと、aとbから
KmとVmaxが算出できる。
14
直線回帰のプログラムの開発
アルゴリズム(一例)
はじめ
データ数(n)入力
Σx, Σy, Σxx,
Σyy, Σxyの計算
a,b,r2の出力
No
データセット
(xi,yi)入力
勾配bの計算
一般式/M-M式
の入力
切片aの計算
Km,Vmaxの計算
決定係数r2の計算
Km,Vmaxの出力
Yes
No
M-M式データ?
Yes
データセット
(xi,yi)逆数演算
M-M式データ?
直線回帰計算
ルーチン
おわり
15
直線回帰のプログラムの開発
実験1
透過係数の実験式(切片・勾配)と決定係数を求めよ!
Equation! ----> Y = 0.2930 + 0.0037 X
Regression ---> r2 = 0.9978
実験2
ミハエリス定数(Km)、最大速度(Vmax)および直線回帰
の決定係数を求めよ!
Equation! ----> Y = 0.0690 + 0.9578 X
Km = 13.88 mg/dL Vmax = 14.49 mg/min
Regression ---> r2 = 0.9999
16
関数
プログラムが、以下の構成の場合!
1) 同じ内容のブロックを何度も
記述しないといけない
2) 1つのブロックが冗長
すっきりしたプログラムを作成したいですね!
すっきりしたプログラムは、デバッグ効率を
格段に向上させ、メンテナンスも楽になります!
main()
{
Block_A
・・・・
Block_A
Block_A
・・・・
Block_A
}
1)や2)のブロックをmain()以外の箇所に記載(関数)し、main()
の実行したい当該箇所とリンクする! main()がすっきりします
17
関数のしくみ
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(); 次の処理へ
}
18
関数の定義
構文 <#include文からmain()の間に記載>
戻り値の型 関数名(仮引数リスト)
z  f x, y
{
変数宣言;
int f(int x, int y)
(例1)
intに限りません
{
文;
int z;
return 式or値;
z = x + y;
}
return z;
← これが戻り値
}


void output(void)
(例2)
{
戻り値なし;引数なし;
printf(“関数名output!\n”);
voidは省略可能!
} 戻り値なしの場合、return 文を省略可19
void: 該当なし!
関数のよびだし 1
構文
1) 関数の戻り値が void
関数名(実引数リスト);
2) 関数の戻り値が 値
変数 = 関数名(実引数リスト);
関数は何度もよびだせる!
voidの実引数は空欄にする
関数定義部
void output(void)
{
printf(“output!\n”);
}
main()
{
output();
output(); 関数よびだし
}
20
関数を呼び出すと、定義しておいた処理がまとめて行なわれる
関数のよびだし 2
void output(void)
{
printf(“output!\n”);
}
関数定義部
2) 関数の戻り値が 値
void ope1(void)
変数 = 関数名(実引数リスト); {
output(); 関数よびだし
関数はmain()中だけでなく、
}
任意の関数中からもよびだせる! main()
(カスケードできる)
{
関数よびだし
ope1();
全てのよびだしはmain()に帰着
}
構文
1) 関数の戻り値が void
関数名(実引数リスト);
21
関数の利用(練習)
問題1 関数を用いて、以下の出力を行うプログラム
を開発してください。関数名は、任意です。
「関数のよびだし1または2」を参考に以下のアルゴ
リズムに従って作成してください。。。
<アルゴリズム>
1 main()にて任意名の関数()をよびだす
2 1の関数内にてprintfを利用して出力する
仮引数および戻り値
voidの関数を用いる
% a.out
2値を入力してください。
%
22
関数の引数 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万円です
23
関数の引数 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
いくら?
24
100万円と200万円です
関数の引数 3
構文
戻り値の型 関数名(仮引数リスト)
void output(void)
(例)
{
printf(“C言語大好き\n”);
}
main()
{
int x;
output(); /*実引数:なし*/
}
プログラムを断片化する
と、プログラムが理解し
やすくなる。引数のない
関数を用いて、プログラ
ムを分散させよう。
戻り値および引数の型
voidは、省略可能。
% a.out
C言語大好き
注意事項:C言語は、基本的に実引数の値の更新を許さない!25
残念ながら、引数は情報を流すだけ。
戻り値
構文
1) 関数の戻り値が void
関数名(引数リスト);
2) 関数の戻り値が 値
変数 = 関数名(引数リスト);
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); 関数よびだし
しなくてはならない(ここではint)。 }
関数内の計算結果(戻り値)は、
1つだけ、return 文でよびだし
元に返還される。
26
関数の利用(練習)
問題2 入力された任意の2つの倍精度浮動小数の
大きい数と小さい数を判断する判別関数を作成し、
大小関係を出力するプログラムを作成してください。
判別関数の名前は任意です。
<アルゴリズム>
1 main()で2つの倍精度浮動小数を入力させる。
2 2つの数を判別関数に渡し、大小関係を検討し、
関数内で、大小関係を出力(printf)する。
判別関数は、引数あり戻り値なしの関数を用いる
27
関数の利用(練習)
問題3 問題2のプログラムに、倍精度浮動小数2値
の四則演算を行う演算関数を加え、以下のアルゴリ
ズムに従って作成してください。関数名は、任意です。
<アルゴリズム>
1 main()にて任意の2値を入力させる(問題2で完
了)。
2 四則演算を別々に行う4つの関数を作成する。
3 main()にて関数の戻り値(四則演算結果)を出力
する。
演算関数は、引数あり戻り値ありの関数を用いる
28
次回の予定
○ 次回
1/14
関数つづき (テキスト:Lesson8)
関数の利用
変数のスコープ など
29
おわりに
• さて、問題です。
1.関数の構文を示してください。
2.「実引数」と「仮引数」って何?
3.その他、質問など
30