Microsoft PowerPoint - 10.ppt [互換モード]

Similar documents
Microsoft PowerPoint - 13.ppt [互換モード]

関数 C 言語は関数の言語 関数とは 関数の定義 : f(x) = x * x ; 使うときは : y = f(x) 戻り値 引数

Microsoft PowerPoint - 12.ppt [互換モード]

Microsoft PowerPoint - 12.ppt [互換モード]

関数の動作 / printhw(); 7 printf(" n"); printhw(); printf("############ n"); 4 printhw(); 5 関数の作り方 ( 関数名 ) 戻り値 ( 後述 ) void である. 関数名 (

Microsoft Word - 03

プログラミング入門1

Microsoft PowerPoint - 計算機言語 第7回.ppt

関数の中で宣言された変数の有効範囲はその関数の中だけです さっきの rectangle _s で宣言されている変数 s は他の関数では使用できません ( 別の関数で同じ名前の変数を宣言することはできますが 全く別の変数として扱われます このように ある関数の中で宣言されている変数のことをその関数の

プログラミング入門1

Microsoft Word - no11.docx

Microsoft PowerPoint - ca ppt [互換モード]

gengo1-11

Microsoft PowerPoint - prog07.ppt

プログラミング実習I

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

Microsoft PowerPoint - 11.ppt [互換モード]

Microsoft Word - no13.docx

メソッドのまとめ

Microsoft PowerPoint - 2.ppt [互換モード]

情報処理Ⅰ演習

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

Microsoft Word - no12.doc

スライド 1

Microsoft PowerPoint - prog08.ppt

Microsoft PowerPoint - C言語の復習(配布用).ppt [互換モード]

Taro-再帰関数Ⅲ(公開版).jtd

gengo1-10

/* do-while */ #include <stdio.h> #include <math.h> int main(void) double val1, val2, arith_mean, geo_mean; printf( \n ); do printf( ); scanf( %lf, &v

Taro-再帰関数Ⅱ(公開版).jtd

C言語7

6 関数 6-1 関数とは少し長いプログラムを作るようになると 同じ処理を何度も行う場面が出てくる そのたびに処 理を書いていたのでは明らかに無駄であるし プログラム全体の見通しも悪くなる そこで登場す るのが 関数 である 関数を使うことを 関数を呼び出す ともいう どのように使うのか 実際に見て

slide5.pptx

Microsoft PowerPoint - 09.pptx

memo

講習No.12

Taro-最大値探索法の開発(公開版

PowerPoint プレゼンテーション

Microsoft PowerPoint ppt

Microsoft PowerPoint - 11.pptx

kiso2-09.key

1 return main() { main main C 1 戻り値の型 関数名 引数 関数ブロックをあらわす中括弧 main() 関数の定義 int main(void){ printf("hello World!!\n"); return 0; 戻り値 1: main() 2.2 C main

Cプログラミング1(再) 第2回

memo

PowerPoint プレゼンテーション

配列, 関数, 構造体

プログラミング及び演習 第1回 講義概容・実行制御

Microsoft PowerPoint - 4.ppt [互換モード]

C プログラミング 1( 再 ) 第 4 回 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ 1

情報処理 Ⅱ 2007 年 11 月 26 日 ( 月 )

kiso2-06.key

Microsoft Word - Training10_プリプロセッサ.docx

#include<math.h> 数学関係の関数群で sin() cos() tan() などの三角関数や累乗の pow() 平方根を求める sqrt() 対数 log() などがあります #include<string.h> 文字列を扱う関数群 コイツもまた後日に 4. 自作関数 実は 関数は自分

Microsoft PowerPoint - CproNt02.ppt [互換モード]

プログラミング基礎I(再)

memo

Microsoft Word - no15.docx

Prog1_6th

株式会社アルウィン C 言語コーディング規約 ver.0.1

講習No.10

基礎プログラミング2015

2. 整数の値を 3 つ 引数として受け取ってそのうち最大の値を返す関数 int max(int a,int b,int c) 3 つの中からの最大値, と値が少ないので, 配列を使わずにごり押しで最大値を求めてみ ました. 配列を使う方法については今までの解答を見ればわかるはずです. その場合受け

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdiu.h> #define InFile "data.txt" #define OutFile "surted.txt" #def

ex05_2012.pptx

Microsoft PowerPoint - 11th.ppt [互換モード]

Microsoft PowerPoint L07-Imperative Programming Languages-4-students ( )

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

Microsoft PowerPoint - 3.ppt [互換モード]

Taro-リストⅠ(公開版).jtd

プログラミング基礎

kiso2-03.key

書式に示すように表示したい文字列をダブルクォーテーション (") の間に書けば良い ダブルクォーテーションで囲まれた文字列は 文字列リテラル と呼ばれる プログラム中では以下のように用いる プログラム例 1 printf(" 情報処理基礎 "); printf("c 言語の練習 "); printf

PowerPoint プレゼンテーション - 物理学情報処理演習

演算増幅器

PowerPoint Presentation

Microsoft PowerPoint - 4.pptx

C C UNIX C ( ) 4 1 HTML 1

分割コンパイル (2018 年度 ) 担当 : 笹倉 佐藤 分割コンパイルとは 一つのプログラムのソースを複数のソースファイルに分けてコンパイルすること ある程度大きなプログラムの場合ソースファイルをいくつかに分割して開発するのが普通 1

PowerPoint プレゼンテーション - 物理学情報処理演習

C 言語第 3 回 2 a と b? 関係演算子 a と b の関係 関係演算子 等しい a==b 等しくない a!=b より大きい a>b 以上 a>=b より小さい a<b 以下 a<=b 状態 真偽 値 条件が満たされた場合 TRUE( 真 ) 1(0 以外 ) 条件が満たされなかった場合 F

Microsoft Word - no205.docx

Microsoft PowerPoint - prog04.ppt

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

4-4 while 文 for 文と同様 ある処理を繰り返し実行するためのものだが for 文と違うのは while 文で指定するのは 継続条件のみであるということ for 文で書かれた左のプログラムを while 文で書き換えると右のようになる /* 読込んだ正の整数値までカウントアップ (for

Taro-2分探索木Ⅰ(公開版).jtd

Microsoft Word - no204.docx

C のコード例 (Z80 と同機能 ) int main(void) { int i,sum=0; for (i=1; i<=10; i++) sum=sum + i; printf ("sum=%d n",sum); 2

プログラム言語及び演習Ⅲ

Microsoft Word - Cプログラミング演習(1)_2012

JavaプログラミングⅠ

Prog1_6th

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdio.h> #define InFile "data.txt" #define OutFile "sorted.txt" #def

スライド 1

PowerPoint Presentation

PowerPoint プレゼンテーション

memo

概要 プログラミング論 変数のスコープ, 記憶クラス. メモリ動的確保. 変数のスコープ 重要. おそらく簡単. 記憶クラス 自動変数 (auto) と静的変数 (static). スコープほどではないが重要.

Taro-プログラミングの基礎Ⅱ(公

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

Transcription:

第 10 回関数と再帰 1

今回の目標 再帰的な考え方に慣れる C 言語における再帰関数を理解する 階乗を求める再帰的な関数を作成し その関数を利用するプログラムを作成する 2

階乗 n! の 2 つの数学的表現 (1) 繰り返しによる表現 n! = 1 2 i n n = ii i= 1 ( n 1 のとき ) ( なお 0!=1) (2) 漸化式による表現 n! = 1 n = 0のとき n ( n 1)! n 1 のとき 3

再帰 関数が自分自身を呼び出す事 C 言語では 再帰的な関数を扱える 書式 : 戻り値の型関数名 ( 仮引数の宣言付きリスト ) 関数名 ( 実引数リスト ); return 式 ; 同じ関数名 注意 : 再帰関数は 漸化式で表わされている数学的な関数などを直接プログラミングすることができる 4

再帰関数例 int fact(int n) int fac; if(n==0) fac=1; else fac=n * fact(n-1); return fac; 再帰呼びだしといいます 5

再帰の典型的な書き方 書式だけを抽出 int 関数名 (int n) if(n==0) /* 再帰関数の基礎 */ ans=???? else /* 再帰部分 */ ans= 関数名 (n-1); return ans; 必ず再帰の基礎 ( 出口 ) をつくる事 再帰呼び出しをするときには 必ず出口に近づくようにすること 6

プログラムの制御の流れ main 1 回目の fact 2 回目の fact 3 回目の fact 4 回目の fact main fact(3) fact(2) fact(1) fact(0) fact(3) fact(2) fact(1) fact(0) return 3*2!; return 2*1!; return 1*0!; return 1; 再帰の深さ 再帰の基礎部分この制御中には 再帰呼び出しには出会わない 7

再帰と変数のスコープ たとえ同じ変数名でも 再帰の深さが違えば 違うローカル変数として扱われる 再帰の深さ main 深さ 1 の fact 深さ 2 の fact main int fac; fact(3) int fac; fact(2) int fac; fact(3) fact(2) fact(1) 深さ 0 の fac 深さ 1 の fac 深さ 2 の fac 8

イメージ 再帰関数は 自分自身のコピーに仕事を押し付ける fact(n) fact(n-1) fact(n-2) メモメモメモ コピー毎に メモがある ( 変数の有効範囲が異なる ) 再帰の基礎部分ここでは コピーを作らない 9

練習 1 /* print_depth.c p 再帰関数実験 1 コメント等一部省略 */ #include<stdio.h> #define MAX 10 /*nの最大値 見栄えを制御*/ int fact(int n); /* 階乗 n! を求める再帰的な関数再帰の深さも表示する */ void print_dot(int k); /* 仮引数分ドットを表示する関数 */ int main() int n; /*n! の n*/ int fac;/* 階乗 */ printf("n=? "); scanf("%d",&n); fac=fact(n); printf(" n"); printf("%d! = %5d n",n,fac); return 0; /* 続く */ 10

int fact(int n) int fac; /* 続く */ print_dot(max-n); /* 再帰の深さのドット表示 */ printf("called by n= %d n",n);/* 仮引数の値を表示 */ if(n==0) /* 再帰の基礎部分 */ fac=1; print_dot(max-n); /* 再帰の深さのドット表示 */ printf("reached BASIS 0!=1 n"); else /* 再帰部分 */ return fac; fac=n*fact(n-1); print_dot(max-n); /* 再帰の深さのドット表示 */ printf("%d!= %d * ( %d! ) n",n,n,n-1); nnn-1); 11

/* 仮引数分のドットを表示する関数 */ void print_dot(int k) int i; for(i=0;i<k;i++) return; /* おしまい */ printf(".."); 12

終わらない再帰関数 1 再帰関数は 必ず基礎 ( 出口 ) 部分に辿りつけないといけない 基礎が無い再帰関数 /* 終わらない関数 1*/ int fact(int n) int fac; fac=n*fact(n-1); return fac; 出口の無い迷路のようなもの プログラムが停止しないときには ^C( コントロール + c ) で停止させましょう 再帰関数は ちょっと注意を怠ると すぐに終わらないプログラムになってしまうので注意する事 13

終わらない再帰関数 2 再帰関数は 必ず基礎 ( 出口 ) 部分に辿りつけないといけない 出口に近づかない再帰関数 /* 終わらない関数 2*/ int fact(int n) 再帰関数は ちょっと注意 を怠ると すぐに終わらな int fac; いプログラムになってしまうので注意する事 if(n==0) else fac=1; return fac; fac=n*fact(n); 無限増殖関数の出来上がり プログラムが停止しないときには ^C( コントロール+ c ) で停止させましょう 14

終わらない再帰関数 3 再帰関数は 必ず基礎 ( 出口 ) 部分に辿りつけないといけない 出口から遠ざかる再帰関数 /* 終わらない関数 3*/ int fact(int n) 再帰関数は ちょっと注意 を怠ると すぐに終わらな int fac; いプログラムになってしまうので注意する事 if(n==0) else fac=1; return fac; fac=n*fact(n+1); 無限増殖関数が出来上がる プログラムが停止しないときには ^C( コントロール+ c ) で停止させる 15

再帰と繰り返し 再帰的な関数は 繰り返しを用いて書き直せることがある 再帰を用いてプログラミングするか 繰り返しを用いてプログラミングするかは よく考えて決めること int fact(int n) int i; int fac; fac=1; for(i=1;i<=n;i++) return fac; fac =fac*i; 16

再帰とスタック スタックとは 後入れ先出し (Last In First Out,LIFO) のデータ構造 再帰関数はその呼ばれた順序にスタックにつまれ 最後に呼ばれたものから終了する 再帰関数をf() として 以下では説明する main から call f(3) call f(2) call f(1) call f(0) return f(1) へ f(2) へ f(3) へ call f(0) return return mainへ return main f(3) f(3) main f(2) f(2) f(3) f(1) f(2) f(3) f(2) f(3) main main main main f(1) f(0) f(1) f(3) i main 17 f(2) f(3)

再帰のイメージ 元の問題 同型 の小さい問題は小問題に分割各個撃破 18

繰り返しのイメージ 元の問題 均等 に小さく分割 小さい問題は各個撃破 19

再帰的に階乗を求めるプログラム (p.123) /* 作成日 :yyyy/mm/dd 作成者 : 本荘太郎学籍番号 :B0zB0xx ソースファイル :fact_rec.c 実行ファイル :fact_rec 説明 : 再帰的にn! を求める関数を用いて n! を計算する 入力 : 標準入力から0から15までの整数 nを入力 出力 : 標準出力に n! を出力 */ #include<stdio.h> /* プロトタイプ宣言 */ int fact(int n); /* 階乗 n! を求める再帰的な関数 */ /* 次のページに続く */ 20

int main() /* ローカル変数宣言 */ int n; /*n! のn*/ int fac; /* 階乗 n!*/ /* 入力処理 */ printf(" 階乗 n! を計算します n"); printf("n=? n"); scanf("%d",&n); /* 入力値チェック */ if(n<0 15<n) printf( nは0から15までの整数にする n"); return -1; /* これ以降では 0 から 15 までの整数 */ /* 続く */ 21

/* 続き */ /* 階乗 n! の計算 */ fac=fact(n); f /* 出力処理 */ printf("%d! = %10d n",n,fac); return 0; /* 続く */ 22

/* 階乗を求める再帰的関数仮引数 n: n! のn(n n,(n は 0 から 15) 戻り値 :n! */ int fact(int n) /* ローカル変数宣言 */ int fac; /* 階乗 n!*/ /* 次に続く */ 23

/* 漸化式に基づく 階乗の定義式 */ if(n==0) else return fac; /* 再帰の基礎 0!=1*/ fac=1; /* 再帰部分 n!=n*(n-1)!*/ )*/ fac=n * fact(n-1);/* 再帰呼び出し */ 24

実行例 $make gcc fact_rec.c -o $./fact_rec 階乗 n! を計算します n=? 5 5! = 120 $ fact_rec $./fact_rec 階乗 n! を計算します n=? -1 nは0から15までの整数にする $ 25