情報処理Ⅱ 2006年12月8日(金).

Slides:



Advertisements
Similar presentations
情報処理Ⅱ 第12回 2005 年 01 月 18 日(火). 2 本日学ぶこと 前処理指令 関数プロトタイプ ライブラリ関数の活用 関数は  すでにあるものを使うか?  関数として定義するか?  関数形式マクロとして定義するか?
Advertisements

15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
情報処理Ⅱ 2007年12月17日(月).
OSとコマンド OS:コンピュータを使うための基本プログラム コマンド:OS上で使用できる命令 OS本体であるカーネルの内部コマンド
情報処理Ⅱ 2005年12月9日(金).
情報処理Ⅱ 2005年12月22日(木).
第8回 プログラミングⅡ 第8回
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
精密工学科プログラミング基礎 第9回資料 (12/11 実施)
情報処理Ⅱ 2006年1月13日(金).
情報処理Ⅱ 第9回 2004年12月7日(火).
情報工学科 3年生対象 専門科目 システムプログラミング 第5回、第6回 ヒアドキュメント レポート課題 情報工学科 篠埜 功.
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
関数とポインタ 値呼び出しと参照呼び出し swapのいろいろ 関数引数 数値積分
関数の定義.
第10回関数 Ⅱ (ローカル変数とスコープ).
情報処理Ⅱ 2007年12月3日(月) その2.
プログラミング演習I 2003年6月25日(第10回) 木村巌.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
プログラミング入門2 第11回 情報工学科 篠埜 功.
前回の練習問題.
第9回関数Ⅰ (簡単な関数の定義と利用) 戻り値.
第7回 プログラミングⅡ 第7回
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
第11回 プログラミングⅡ 第11回
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
精密工学科プログラミング基礎Ⅱ 第4回資料 今回の授業で習得してほしいこと: 文字列の扱い ファイル入出力の方法 コマンドライン引数の使い方
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
情報処理Ⅱ 第14回 2006年1月23日(月).
情報処理Ⅱ 第2回:2003年10月14日(火).
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
プログラミング基礎a 第6回 C言語によるプログラミング入門 配列と文字列(その2)
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
第5回 プログラミングⅡ 第5回
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
情報処理Ⅱ 2006年11月24日(金).
情報処理Ⅱ 第7回 2004年11月16日(火).
コンパイラ 2012年10月11日
プログラミング 4 文字列.
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
関数と再帰 教科書13章 電子1(木曜クラス) 2005/06/22(Thu.).
情報処理Ⅱ 2007年2月2日(金).
プログラミング演習I 2003年6月11日(第9回) 木村巌.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
情報処理Ⅱ 第2回 2004年10月12日(火).
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
情報処理Ⅱ 2005年11月25日(金).
プログラミング演習II 2004年11月 16日(第5回) 理学部数学科・木村巌.
第10回 関数と再帰.
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
情報処理Ⅱ 第9回:2003年12月16日(火).
プログラミング入門2 第5回 配列 変数宣言、初期化について
情報処理Ⅱ 小テスト 2005年2月1日(火).
計算技術研究会 第5回 C言語勉強会 関数(function)を使う
岩村雅一 知能情報工学演習I 第13回(後半第7回) 岩村雅一
情報処理Ⅱ 第8回:2003年12月9日(火).
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
Presentation transcript:

情報処理Ⅱ 2006年12月8日(金)

本日学ぶこと 関数の補足 既存のプログラムから関数を「抽出する」方法 再帰(recursion) クイックソート

関数の抽出 反復語判定プログラム(第7回)を例として 関数を抽出することで一般に 関数抽出の要点 コード量(プログラムのサイズ,ステップ数)は増える. しかし,それぞれの関数のコード量は減り,関数ごとに役割が明確になるため,読みやすい. 関数抽出の要点 ①関数名,②戻り値の型,③仮引数 の順に決める. 変数の有効範囲に注意する. 変数の除去や複製が必要なこともある. 保守性向上

再帰呼び出しとは 関数の内部で自分自身を呼び出すことを,再帰呼び出し(リカーシブコール,recursive call)という. 用途 注意点 再帰的(帰納的,循環的)な定義 バックトラック(backtrack) 分割統治法(divide-and-conquer) 注意点 無限ループにならないようにする. 再帰を使わないほうがよいこともある.

カウントダウンするプログラム 自作関数countdownの定義の中で,countdownを呼び出している.

カウントアップするプログラム 出力の位置を変えると,カウントアップになる. カウントアップ,カウントダウンともに,再帰呼び出しなしの プログラムのほうが,効率はよい. なぜ再帰呼び出しは効率が悪いか? …関数呼び出しのコスト(オーバーヘッド)があるから. 業務としてのプログラミングで,再帰呼び出しを使用してはならないと(コーディング規約で)定めていることも 再帰呼び出しはしてはいけないと書いている例: 『組み込みソフトウェア開発向けコーディング作法ガイド』p.49 『ずっと受けたかったソフトウェアエンジニアリングの授業2』pp.121-122

なぜ再帰呼び出しが可能なのか? 同一の変数名x に対して複数の このようなデータ 構造を,「スタック」 オブジェクトが という. 生成される. このようなデータ 構造を,「スタック」 という. countdown x = 0 countdown x = 1 countdownの再帰呼び出しを終えたときの戻り先 countdownの呼び出し(関数処理)を終えたときの戻り先 countdown関数処理時に 生成されるオブジェクト main x = 2 Cの規格として「スタック」が必須ということではない. しかし,関数呼び出しの構造(mainから関数Aを呼び出し,関数Aの中で関数Bを呼び出し,関数Bの処理を終えたら, 制御は,mainではなく,「関数Aの中で関数Bを呼び出したところ」に戻らなければならない(そして,関数Aの処理を 終えたら,制御は,mainの中で関数Aを呼び出したところに戻る))を実行時に保持するには,スタックが最も合理的 ということである. main関数処理時に 生成されるオブジェクト num = 2

再帰的な定義の例(1) 階乗 フィボナッチ数列 再帰呼び出しを用いれば,シンプルに書ける. 0! = 1, 1! = 1 n! = n×(n-1)! (n≧2) フィボナッチ数列 a1 = 1, a2 = 1 an = an-1 + an-2  (n≧3) 再帰呼び出しを用いれば,シンプルに書ける. しかしこれらも,whileループのほうが効率がよい.

再帰的な定義の例(2) 木構造 再帰呼び出しは必要? トーナメント表の決勝戦から順に見て, 優勝チームの戦績を知る 100万個の記録から,欲しいものを 瞬時に獲得する ホームディレクトリ以下のすべての ファイル名を出力する 再帰呼び出しは必要? するのが自然な場合と,してはいけない 場合がある 呼び出し方よりもデータ構造のほうが重要 「ホームディレクトリ以下のすべてのファイル名を出力する」には,いちいちプログラムを作らなくても, 「find ~」を実行するだけでいい.

分割統治法 対象領域を細分化(分割)して求め(統治),全体として正しい解になるようにする. 例: クイックソート 4 7 3 8 6 1 2 5 2 8 5 7 6 1 3 4 「4より小」と 「4より大」に 分ける. 1 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8

クイックソートの関数呼び出し 配列領域,開始位置,終了位置を引数とする. 4 7 3 8 6 1 2 5 2 3 1 4 6 7 8 5 1 詳細は, http://www.wakayama-u.ac.jp/~takehiko/ipii2004/20041207/slideindex.html のpp.21~23を参照のこと. 1 2 3 4 5 6 7 8

関数の呼び出し関係 (quicksort.c) main swap get_array_length quicksort print_score 再帰!

まとめ 再帰呼び出しを用いて関数を定義すると,プログラムがすっきり書けることがある. 一般に,再帰を用いないほうが効率的である. 再帰的に定義された問題に適用すると,効果的. 一般に,再帰を用いないほうが効率的である. 関数内のauto変数は,関数呼び出しごとに生成される.

情報処理Ⅱ 2006年12月8日(金)の2

ここで学ぶこと ライブラリ関数の活用 (参考)関数の分類 先人の知恵を活用する. 勉強・授業のためでなければ, ライブラリ関数と同じ名前や機能の関数は自作しない. (参考)関数の分類 自作関数: 自分で定義する.⇒ 12月1日のテーマ ライブラリ関数: 出来合いのもの.printfなど.⇒ ここでのテーマ

ライブラリ関数とヘッダファイル 既に定義されている関数や定数を利用するには,あらかじめ,適切なファイル名(ヘッダファイル)を記載しておく. printf なら #include <stdio.h> CHAR_BIT なら #include <limits.h> ライブラリ関数と,記載すべきヘッダファイル名は,manpage で知ることができる. man 3 printf jman 3 printf JM Project (http://www.linux.or.jp/JM/) ヘッダファイルはコンパイル環境が保有しているが,その所在は,環境による. Vine Linuxのコマンド

ヘッダファイルとインクルード ヘッダファイルには,定数,構造体や特殊な型,関数プロトタイプなどが宣言・定義されている. #include <stdlib.h> とすると,/usr/include/stdlib.h を取り込む(インクルードする). 慣例として,ファイル名は「.h」で終わらせる. ヘッダファイルの中で,他のヘッダファイルをインクルードすることもよく行われる. ヘッダファイルを自作することもある.そのファイルをインクルードするときは,#include "headerfile.h" のように書く. 「.c」や「.h」などを,Windowsユーザは「拡張子」と呼んでいるが, Unix文化では「サフィックス(suffix)」と呼ばれている.

有用なライブラリ関数(1) #include <stdio.h> を必要とするもの int printf(const char *format, ...); int scanf(const char *format, ...); int putchar(int c); … 1文字出力 int getchar(void); … 1文字入力 int sprintf(char *str, const char *format, ...); … printfと同様に文字列を構成し,結果をstr(の指し示す配列領域)に格納する 可変引数 と呼ばれる 可変引数 と呼ばれる

有用なライブラリ関数(2) #include <stdlib.h> を必要とするもの int atoi(char *s); … 文字列から整数値への変換 void exit(int status); … プログラムの終了 int rand(void); … 乱数生成 #include <string.h> を必要とするもの size_t strlen(char *s); … 文字列の長さ int strcmp(char *s1, char *s2); … 文字列比較 char *strstr(char *s1, char *s2); … 文字列検索 char *strcat(char *dest, char *src); …文字列連結 #include <string.h>を必要とするものについて, strcatのdestを除き,char *型の仮引数には,constがつく.

有用なライブラリ関数(3) #include <ctype.h> を必要とするもの int isdigit(int c); … 文字が数字であるか判定 isalphaは英字判定,isalnumは英数字判定 int tolower(int c); … 大文字を小文字に変換 大文字以外の文字はそのまま 逆はtoupper #include <math.h> を必要とするもの double exp(double x); … eのx乗 double floor(double x); … x以下で最小の整数 最大はceil,四捨五入(丸め)はround コンパイル時,「cc -lm program.c」のようにリンカオプション(linker option)が必要

関数名の表記 printf関数,関数printf printf()関数,関数printf() printf(3) この授業で採用している. 関数名であることを明確にする表記法.よく見かける. printf(3) 「printfというライブラリ関数があって,詳細は, man 3 printfを実行すれば得られる」の意味. 「(1)」ならコマンド,「(2)」はシステムコール man printfを実行すると,ライブラリ関数ではなく,コマンドとしてのprintfの使い方が出てくる. 「printfの実引数に3と書く」ではない.