a[2]

C言語
第9講
生物機能制御学講座 濱田
農学部7号館209室
1
本日の講義内容
• おさらい
for ・ while ・ do{}while文
• 配列
テキスト Lesson 7
• プログラムの作成
• アンケート
2
アンケート結果
質問および要望
1.これまでの講義で困難だった点
全部
2名
乱数
1名
scanf
1名
if switch
1名
for while do{}while 26名
2.問題の数式の立て方?
Loop内の数式:漸化式を導出しよう!
3.問5のプログラムが無限loopになる
ON/OFFスイッチ的な変数を導入しよう!
3
何度も繰り返す
用途例
○ 繰返し入力または出力
printf, scanf
○ 繰返し演算
n
X  i
i 1
m
Y   j
j 1
Z  !
○ 繰返し実行
a.outを終了せずに何度も
同じプログラムを実行する。
4
繰返し文
C言語の繰返し文
人気No.1
○ for 文
for(i=1;i<=n;i++) { 文・・・ }
人気No.2
○ while 文
while(i<=n) { 文・・・ }
○ do ~ while 文
do { 文・・・ }while (i<=n);
5
for 文
構文
for(初期値設定の式;条件式;変化量) {
文1; 文2; ・・・・・
条件式が真の場合:{}内を実行!
}
初期値設定の式 制御変数(カウンタ)を準備
カウンタの初期値設定
条件式
if 文でも用いた条件式
例:カウンタの最大(最小)値を判定
変化量
初期値からの増分(減分)
6
備考
カウンタの変数宣言(int型)
while 文
構文
while(条件式) {
文1; 文2; ・・・・・
条件式が真の場合:{}内を実行!
}
条件式
if 文でも用いた条件式
例:カウンタ最大(最小)値を判定
備考1
条件式では、関係演算子 or
論理演算子を適用
条件式の評価値はwhile{}内
で更新される(ことが多い)
7
備考2
do{}while 文
構文
do{
文1; 文2; ・・・・・ 最低1回は{}が実行される
条件式が真の場合:{}内を実行
} while(条件式)
条件式
備考1
備考2
if 文でも用いた条件式
例:カウンタ最大(最小)値を判定
条件式では、関係演算子 or
論理演算子を適用
条件式の評価値はdo{}while内
で更新される(ことが多い)
8
文のネスト(入れ子)
for文、if文などの多重の繰り返しを行う
注意:カウンタ変数は別にすること
int i,j;
for(i=1;i<=10;i++) {
f
for(j=1;j<=10;j++) {
f
o
o
i
if (i<j) {
r
r
f
printf(“i<jだよ!\n”);
i
}
j
L
B
l
o
else {
L
o
o
printf(“i>=jだよ!\n”);
o
c
p
}
o
k
p
} /* for j end. */
} /* for i end. */
9
break文とcontinue文
繰り返し処理の流れの変更に適用!
break文
構文 break;
→ break文以後の繰り返し処理を強制的に終了し、
for・while・if・switch文などのブロックから抜
け出る。
continue文
構文 continue;
→ continue文以後のその回の繰り返し処理を
飛ばし、 for・while文などのブロックの先頭へ戻
り、次の繰り返し処理を継続する(カウンタは+1)。
10
配列
規則性を有する多数のデータを扱って集計や解析を行
なうとき、各々のデータを格納する変数を多数準備しな
くてはなりません。手抜きしたいですねぇ。
これまでの技術では・・・
int X0,X1,X2,………,X9;
scanf(“%d”,X0);
scanf(“%d”,X1);
・・・・・・・・・・・・・・・
scanf(“%d”,X9);
こんな技術があります・・・!
int X[10], Y[10], i;
for(i=0;i<10;i++){
scanf(“%d”,&X[i]); }
すっきりとしたコーディ
ングが可能です!
11
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)まで
12
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)まで
13
配列の利用
① 配列要素への値の代入
配列名[添字]=式 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”は初登
場
14
配列の利用
③ 配列要素へキーボードから値入力
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)配列の値を参照するときは添字に気を配ること
15
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]); }
添字出力
16
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
17
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 ”,f[i][j]); }}
18
2
共通項目
と
は、要素数に応じて変更する必要あり!
3
きょ
マクロ(#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. */
19
1次元数値配列の初期化
float doubleも同じルールです!
① 基本形
型名 配列名[要素数]={値1,値2,・・・ };
例 int a[5] = {80,60,50,40,30};
要素数を記
② 省略形
載しない
型名 配列名[]={値1,値2,・・・ };
例 int a[] = {80,60,50,40,30};
③ 応用形
型名 配列名[要素数(例≧3)]={値1,値2};
未設定要素
には自動的
例 int a[5] = {80,60};
に”0”格納
配列の初期化は、”宣言”と”値の代入”を同時に実施
省略形の場合、要素数の引用に気を配ること!
20
2次元数値配列の初期化
float doubleも同じルールです!
① 基本形
型名 配列名[行要素数][列要素数]={
{値1,値2,・・・ },{値1,値2,・・・ },{}・・・};
例 int a[2][5] = {
{80,60,50,40,30},{10,20,30,40,50} };
② 省略形
行要素数を
記載しない
型名 配列名[][列要素数]={
{値1,値2,・・・ },{値1,値2,・・・ },{}・・・};
例 int a[][5] = {
{80,60,50,40,30},{10,20,30,40,50} };
配列の初期化は、”宣言”と”値の代入”を同時に実施
省略形の場合、行要素数の引用に気を配ること!
21
文字列と配列の関係
‘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”以上必要である!
22
文字列の操作は、’\0’を利用すると便利である。
1次元文字列配列の初期化
① 基本形
型名 配列名[要素数]={‘文字’,‘文字’,・・・};
例 char str[3] = {‘H’,‘i’,‘\0’,};
要素数を記
② 省略形
載しない
1) 型名 配列名[]={文字列};
例 char str[] = {‘H’,‘i’,‘\0’,};
2) 型名 配列名[要素数]=“文字列”;
例 char str[3] = “Hi”;
文字列末尾
3) 型名 配列名[]=“文字列”;
の‘\0’を
記載しない
例 char str[] = “Hi”;
省略形の3)の適用が多いが、要素数には気を配ること!
23
2次元文字列配列の初期化
① 基本形
型名 配列名[行要素数][列要素数]={
{‘文字’,‘文字’,・・・},{}・・・};
例 char str[2][3] = {
{‘a’,‘b’,‘c’},{‘d’,‘e’,‘f’} };
② 省略形
行要素数を
記載しない
型名 配列名[][列要素数]={
{値1,値2,・・・ },{値1,値2,・・・ },{}・・・};
例 char str[][3] = {
{‘a’,‘b’,‘c’},{‘d’,‘e’,‘f’} };
一次元配列の文字列の初期化の省略形2),3)の方法が
24
使用できないことが多い(コンピュータに依存する)
配列操作の練習
問題1 キーボード入力した任意のN個のデータ(倍精
度浮動小数)を数値配列に格納し、出力するプログラム
を作成しよう。
(アルゴリズム)
1) 入力するデータ数(N)を入力させる
2) N個のデータを入力させる(N回入力)
3) データが入力される度に対応する数値配列
へ格納する
4) 入力が終了する
5) 数値配列に格納されたデータを順に出力する
25
配列操作の練習
問題2 問題1で数値配列に格納したN個のデータの
総和を求め、総和を出力するプログラムを作成しましょう。
ただし、問題1のプログラムに付け加えて作成してくださ
い。
(アルゴリズム)
1) 数値配列に格納されたN個のデータを添字に
着目して、N回繰返し足し算する
(for whileなどの講義で獲得した技術)
2) 総和を出力する!
26
配列操作の練習
問題3 問題1で数値配列に格納したN個の数値デー
タの二乗和を求め、二乗和を出力するプログラムを作成
しましょう。ただし、問題2のプログラムに付け加えて作
成してください。
(アルゴリズム)
1) 数値配列に格納されたN個のデータを各々二乗し、
二乗した値をN回繰返し足し算する
(for whileなどの講義で練習した技術)
2) 二乗和を出力する!
二乗和= (Σ(各データ)2 )
27
配列操作の練習
問題4 問題1で入力したデータ数と、問題2と3で求め
た総和と二乗和を用いて、
L = N*二乗和-総和*総和;
を計算し出力するプログラムを作成しましょう。ただし、
問題3のプログラムに付け加えて作成してください。
(アルゴリズム)
1) 問題1のデータ数、問題2および3で算出した値を
用いて、四則演算する
2) 演算結果を出力する!
28
次回の予定
○ 直線回帰プログラムの開発とそれを用いた
解析に関する課題のレポートを作成する。
○ 関数 (テキスト:Lesson8)
関数の定義 関数の呼び出し など
29
おわりに
• さて、問題です。
1.一次元および二次元配列の宣言書式を
示してください。
2.文字列を配列に代入するとき、
文字列の最後に付記する記号は何ですか?
3.その他、質問など
30
レポート課題
問題
『汎用性の高い直線回帰プログラムの開発』
1) 直線回帰の式を導出してください。
2) 決定係数の式を導出してください。
3) 1)の式を用いて、『汎用性の高い直線回帰を
行なうプログラム』を開発してください。
(汎用性をどこまで高めるかは、皆さんの技術次第)
4) 3)で開発したプログラムに2)の決定係数を算出
する式を加えてください。
次葉
31
レポート課題
問題
『汎用性の高い直線回帰プログラムの開発』
実験1) 生体膜の薬物透過能を評価するため、温度と
透過係数の関係を調べた。開発したプログラムを用いて、
以下の実験データを直線回帰し、透過係数の実験式(切
片・勾配)と決定係数を求めてください。
温度[℃]
10.0 20.0 30.0 40.0 50.0
透過係数[mL/min] 0.33 0.37 0.40 0.44 0.48
次葉
32
レポート課題
問題
『汎用性の高い直線回帰プログラムの開発』
実験2) 肝から単離した酵素をin vitroで評価したい。
この酵素反応系をミハエリスーメンテン型と仮定し、以下
の実験データのミハエリス定数(Km)、最大速度(Vmax)
および直線回帰の決定係数を求めてください。
薬物濃度[mg/dL]
反応速度[mg/min]
10.0 20.0 30.0 40.0 50.0
6.07 8.55 9.91 10.76 11.35
次葉
33
レポート課題
問題
『汎用性の高い直線回帰プログラムの開発』
5) レポート内容 (表紙:レポート名・学籍番号・氏名)
① 直線回帰を導出
② 決定係数を導出
③ 直線回帰プログラムのアルゴリズムを解説
④ 実験1と実験2の解析
⑤ 決定係数などを用いて、解析結果を考察
⑥ 付記:開発した直線回帰プログラムを添付
⑦ 参考文献
34