07 2007 06 25s-okubo/class/...˛˚˜5eq , r e1~7od1pu 2'5 v w struct struct tuvtuv wx wx= w= w;...
TRANSCRIPT
1
1
プログラミング言語2
第07回(2007年06月25日)
2/27
今日の配布物
� 片面の用紙1枚
� 今日の課題が書かれています。
本日の出欠を兼ねています
2
3/27
今日やること
� http://www.tnlab.ice.uec.ac.jp/~s-okubo/class/language/
にアクセスすると、教材があります。
� 2007年06月25日分と書いてある部分が、本日の教材です。
� 本日の内容
� 先週の課題の解答例
� 構造体(前編)
� Lagrangeの補間公式
4/27
第07回の課題の簡単な解説
3
5/27
第07回の課題課題1: 次の仕様を満たす関数 sample03 を作成しなさい。
• sample03 は、引数として2つの整数 x,y を貰う。
• 戻り値として、整数型の値 を返す。
• sample03 は、f(x,y) を計算する際に、再帰を行なう。
• 関数 sample03 の中からは、大域変数を参照しない。
( )
≤
>
+
+
=
10,
10,2,2,
xx
xyx
fyyxf
課題のポイント:
� 問題中のどこを再帰処理で行えばよいか。
� 再帰の停止条件は、きちんとできているか。
問題に書き忘れていたこと:
� 今回、x は正の整数が入力されると仮定して良い。
6/27
回答例
int sample03(int x, int y){
if(x<=10){
return x;
}else{
return y+sample03(x/2,y+2);
}
}
int sample03(int x, int y){
if(x<=10){
return x;
}else{
return y+sample03(x/2,y+2);
}
}
その1/1: � ここでは、関数 sample03 のみ示す。
4
7/27
回答例
int sample03(int x, int y){
if(x<=10){if(x<=10){if(x<=10){if(x<=10){
return x;return x;return x;return x;
}}}}else{
return y+sample03(x/2,y+2);
}
}
int sample03(int x, int y){
if(x<=10){if(x<=10){if(x<=10){if(x<=10){
return x;return x;return x;return x;
}}}}else{
return y+sample03(x/2,y+2);
}
}
その1/1:
停止条件
� x≤10なら、再帰を
行わず、値を返す。
� さもなければ、再
帰を行う。
8/27
回答例
int sample03(int x, int y){
if(x<=10){
return x;
}else{
return y+sample03(x/2x/2x/2x/2,y+2);
}
}
int sample03(int x, int y){
if(x<=10){
return x;
}else{
return y+sample03(x/2x/2x/2x/2,y+2);
}
}
その1/1:
なのに、
2
x
x/2としか書いてない。
整数型/整数型=整数型
なので、小数点以下は、
勝手に切り捨てられる。
5
9/27
第07回の課題課題2:sample03を使って、f(63,5) を計算したときに、
どのように計算が行なわれていくか、説明しなさい。
10/27
再帰の様子sample03(63,5)の実行。� 02行:i > 10 なので、else文以下を実行。� 05行:5+sample03(63/2,5+2)の計算のため、sample03(2)を実行。
01:int sample03(int x, int y){02: if(x<=10){03: return x;04: }else{05: return y+sample03(x/2,y+2);06: }07:}sample03(31,7)の実行。� 02行:i > 10 なので、else文以下を実行。� 05行: 7+sample03(31/2,7+2)の計算のため、sample03(1)を実行。sample03(15,9)の実行。
� 02行:i > 10 なので、if文以下を実行。� 04行: 9+sample03(15/2,9+2)の計算のため、sample03(7,11)を実行。
sample03(15,9)=16なので、23 を戻り値として返す。sample03(15,9)=23なので、28 を戻り値として返す。sample03(7,11)の実行。� 02行:i ≤ 1 なので、else文以下を実行。� 04行:戻り値として7を返す。sample03(7,11)=7なので、16 を戻り値として返す。
6
11/27
再帰の様子
01:int sample03(int x, int y){02: if(x<=10){03: return x;04: }else{05: return y+sample03(x/2,y+2);06: }07:}( ) ( )
( )( )
( )( )( )
( )( )
( )
( )
28
235
1675
7975
29,2/15975
27,2/3175
25,2/6355,63
=
+=
++=
+++=
++++=
+++=
++=
f
f
ff
式で再帰の様子を書くと...
12/27
再帰の様子
01:int sample03(int x, int y){02: if(x<=10){03: return x;04: }else{05: return y+sample03(x/2,y+2);06: }07:}( ) ( )
( )( )
( )( )( )
( )( )
( )
( )
28
235
1675
7975
29,2/15975
27,2/3175
25,2/6355,63
=
+=
++=
+++=
++++=
+++=
++=
f
f
ff
式で再帰の様子を書くと...
再帰呼び出し
再帰呼び出し
再帰呼び出し
停止条件を
満たした
戻り値を返す
戻り値を返す
戻り値を返す
戻り値を返す
7
13/27
構造体(前編)
14/27
構造体とは
� 構造体は、幾つかのデータをひとまとめにした型型型型。
� たとえば、
『整数型のデータ』
『文字型のデータ』
という、 複数のデータを
保存できる。
構造体 sample_kouzou
整数型のデータ
文字型のデータ
� 構造体中の個々のデータを、メンバと言う。
� 次の場合に便利
� 関係している複数のデータを、まとめて管理
したいとき
� 関数に、沢山の値を引き渡したいとき
8
15/27
構造体を使うには
� 構造体を使うときは、次の手順を踏む必要がある。
1. 構造体を定義する。
2. 構造体の型をもつ、変数を宣言する。
3. 変数にアクセスする。
� 構造体は型型型型なので、その型をもつ変数を宣言して使
います。
16/27
構造体の定義
1.1.1.1. 構造体構造体構造体構造体をををを定義定義定義定義するするするする。。。。2. 構造体の型をもつ、変数を宣言する。3. 変数にアクセスする。� 構造体が、どのようなメンバからなっているかを定義。
� 書式は、 次の通り。
struct 構造体の名前 {
メンバーの宣言
}
struct 構造体の名前 {
メンバーの宣言
}
� たとえば、複素数を扱う構造体 complex を定義
struct complex {
double real;
double imaginary;
};
struct complex {
double real;
double imaginary;
};
実数部保存用
虚数部保存用
2つのメンバを持つ構造体
9
17/27
変数の宣言
1. 構造体を定義する。2.2.2.2. 構造体構造体構造体構造体のののの型型型型をもつをもつをもつをもつ、、、、変数変数変数変数をををを宣言宣言宣言宣言するするするする。。。。3. 変数にアクセスする。� 構造体は型なので、その型を持つ変数を宣言する。
� 書式は、 次の通り。
struct 構造体の名前 変数名 ; struct 構造体の名前 変数名 ;
� たとえば、構造体 complex の型をとる変数
com01 と com02 と com03 を宣言するなら...
struct complex com01, com02, com03;struct complex com01, com02, com03;
18/27
変数の宣言
1. 構造体を定義する。2. 構造体の型をもつ、変数を宣言する。3.3.3.3. 変数変数変数変数ににににアクセスアクセスアクセスアクセスするするするする。。。。� 構造体の、それぞれのメンバにアクセスするには、
変数名.メンバ名変数名.メンバ名
� 変数 comp01 のメンバ real の内容にアクセスしたい
なら...
com01.realcom01.real
のように、変数名とメンバ名を . . . . でつなげて書く。
10
19/27
変数の宣言
1. 構造体を定義する。2. 構造体の型をもつ、変数を宣言する。3.3.3.3. 変数変数変数変数ににににアクセスアクセスアクセスアクセスするするするする。。。。� 例では、com01 と com02 と com03 を宣言している
ので、利用できるのは...
com01.real
com01.imaginary
com01.real
com01.imaginary
� 普通の変数と同様に利用することができる。
com02.real
com02.imaginary
com02.real
com02.imaginary
com03.real
com03.imaginary
com03.real
com03.imaginary
com03.real = com01.real + com02.real;
com03.imaginary = com01.imaginary + com02.imaginary;
com03.real = com01.real + com02.real;
com03.imaginary = com01.imaginary + com02.imaginary;
20/27
サンプルプログラム
#include<stdio.h>
struct complex {
double real;
double imaginary;
};
#include<stdio.h>
struct complex {
double real;
double imaginary;
};
その1/2:
� 2つの複素数 com01 と com02 の内容を足して、
com03に代入し、さらにcom03の内容を出力する。
実数部保存用
虚数部保存用
2つのメンバを持つ構造体complexを定義
11
21/27
サンプルプログラム
main(){
struct complex com01, com02, com03;
com01.real=2;
com01.imaginary=3;
com02.real=4;
com02.imaginary=8;
com03.real = com01.real + com02.real;
com03.imaginary = com01.imaginary + com02.imaginary;
printf("com03 is %f + i %f¥n",com03.real,com03.imaginary);
}
main(){
struct complex com01, com02, com03;
com01.real=2;
com01.imaginary=3;
com02.real=4;
com02.imaginary=8;
com03.real = com01.real + com02.real;
com03.imaginary = com01.imaginary + com02.imaginary;
printf("com03 is %f + i %f¥n",com03.real,com03.imaginary);
}
その2/2:
値を代入
普通に計算
22/27
グラフのプロット(復習)
12
23/27
グラフのプロット
� 次の手順でグラフを書くことを考える。
1. Cで書いたプログラムで、xgraph で読み込むデー
タを作る。
2. xgraph で読み込んで、グラフを書く。
� xgraph で読み込むデータの形式
� 複数行からなっている。
� 1つの行に2つの値が書かれている。
� 2つの値は、スペースで区切られている。
24/27
#include<stdio.h>
main(){
double x;
for(x=0;x<=4;x=x+0.2){
printf("%f %f¥n",x,4*x*x-8*x+10);
}
}
#include<stdio.h>
main(){
double x;
for(x=0;x<=4;x=x+0.2){
printf("%f %f¥n",x,4*x*x-8*x+10);
}
}
xgraph で読み込むデータの作成� 例として、 をプロットする。 1084
2+− xx
今回は、 の間を
プロットすることに
40 ≤≤ x
今回は、0.2刻みで
プロットすることに
1つの行に、2つの値を
スペースで区切って書くxと 1084
2+− xx
13
25/27
xgraph で読み込むデータの作成� さきほどのプログラムは、標準出力(今はコンソール)
に対して、結果を出力する。
リダイレクトを使って、結果をファイルに出力する。
./a.out > xgraph.dat
� できたデータを、xgraph でグラフにする。
xgraph xgraph.dat &
26/27
Lagrangeの補間公式
14
27/27
Lagrangeの補間公式
� f(x) が 2次以下の関数であるとする。
また、 a,b,c は異なる実数であるとする。
( ) ( )( )( )
( )( )( )
( )( )
( )( )( )
( )( )
( )( )bcac
bxaxcf
abcb
axcxbf
caba
cxbxafxf
−−
−−+
−−
−−+
−−
−−=
となる。
このとき、 f(x) は一意に定まり、