情報処理Ⅱ 2007年1月26日(金).

Slides:



Advertisements
Similar presentations
情報処理Ⅱ 第10回:2004年1月13日(火). 本日のテーマ 標準入出力 標準入力と標準出力 いくつかの標準入出力関数 記憶域管理関数 malloc, free など 実行時に配列領域を確保する手法 落ち穂拾い 入力の与え方 コメントの書き方 制御文 知っておくべき「 C 言語の文法」
Advertisements

プログラミング演習 II 2005 年 1 月 19 日(第 9 回) 理学部数学科・木村巌. 前回までの復習 共用体( union type ) 共用体( union type ) 列挙 (enumerated type ) 列挙 (enumerated type ) 構造体、構造体のポインタ、
10: ファイル入出力 Linux にログインし、以下の講義ページ を開いておくこと teachers/w483692/CPR1/ C プログラミング入門 総機 1 ( 月 1) 1.
オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
情報処理演習C2 ファイル操作について (2).
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
プログラミング入門2 第10回 動的な領域確保 情報工学科 篠埜 功.
データ構造とアルゴリズム 第10回 mallocとfree
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
基礎プログラミングおよび演習 第9回
第13回 プログラミングⅡ 第13回
12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
記憶クラス 変数をどのような記憶領域に割り当てるかを指定するのが記憶クラス 記憶クラスには、自動変数、静的変数、外部変数などがある。
第8回 プログラミングⅡ 第8回
情報処理Ⅱ 第13回 2006年1月20日(金).
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
精密工学科プログラミング基礎 第9回資料 (12/11 実施)
ファイル操作と文字列の利用.
情報処理Ⅱ 第13回 2004年01月25日(火).
10: ファイル入出力 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
情報処理Ⅱ 2007年11月5日(月).
Cプログラミング演習 第6回 ファイル処理と配列.
プログラミング 2 ファイル処理.
プログラミング論 ファイル入出力
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第2回 ファイル処理 情報・知能工学系 山本一公
プログラミング 4 記憶の割り付け.
プログラミング演習I 2003年6月25日(第10回) 木村巌.
プログラミング入門2 第11回 情報工学科 篠埜 功.
プログラミング入門2 第11回 情報工学科 篠埜 功.
第7回 プログラミングⅡ 第7回
プログラミング論 ファイル入出力
第11回 プログラミングⅡ 第11回
P n ポインタの基礎 5 q m 5 7 int* p; int 型の変数を指すポインタ int* q; int 型の変数を指すポインタ int n=5, m=7; int 型の変数 int array[3]; int* pArray[3]; p = &n; ポインタにアドレスを代入しているのでOK.
四則演算,変数 入力文,出力文,代入文, ライブラリ関数
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
精密工学科プログラミング基礎Ⅱ 第4回資料 今回の授業で習得してほしいこと: 文字列の扱い ファイル入出力の方法 コマンドライン引数の使い方
情報処理Ⅱ 第14回 2006年1月23日(月).
第4回 ファイル入出力方法.
情報処理Ⅱ 第2回:2003年10月14日(火).
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
システムプログラミング 第7回、8回 ファイルシステム関連の システムコール
情報処理Ⅱ 2007年1月19日(金).
C言語 はじめに 2016年 吉田研究室.
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
11: 動的メモリ確保 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング演習I 2003年7月2日(第11回) 木村巌.
ファイルの読み込み, ファイルからのデータの取り出し, ファイルの書き出し
情報処理Ⅱ 第2回 2005年10月14日(金).
情報処理Ⅱ 第2回 2006年10月13日(金).
情報処理Ⅱ 2008年1月28日(月).
第5回 プログラミングⅡ 第5回
情報処理Ⅱ 2006年11月24日(金).
情報処理Ⅱ 第7回 2004年11月16日(火).
情報処理Ⅱ 2005年10月28日(金).
モジュール分割.
プログラミング 4 文字列.
アルゴリズムとデータ構造 補足資料6-1 「サンプルプログラムcat1.c」
11: 動的メモリ確保 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
情報処理Ⅱ 2006年11月8日(金).
情報処理Ⅱ 2007年2月2日(金).
プログラミング演習I 2003年6月11日(第9回) 木村巌.
情報処理Ⅱ 第2回 2004年10月12日(火).
情報処理Ⅱ 2005年11月25日(金).
情報処理Ⅱ 小テスト 2005年2月1日(火).
情報処理Ⅱ 第8回:2003年12月9日(火).
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
Presentation transcript:

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

本日学ぶこと ファイル入出力,標準入力・標準出力 記憶域管理関数(mallocなど) 問題 ファイルを入力にとり,先頭に行番号をつけて出力できる? 標準入力(キーボードなど)からの入力に対して,先頭に行番号を右揃えでつけて出力できる?

ファイルとは(復習) 補助記憶装置に保存する単位となる,データの集まり. プログラムが終了しても,内容が保持されるデータ構造. (比較)変数の値はメモリ上にあるため,プログラム終了時に破棄される. コンピュータの電源を切って入れ直しても,保持されていることが多い. ストリームと呼ばれるバイト列として,読み書き可能. バイト列とは? char配列で表現できるデータ構造. '\0' で終わるものではなく,途中に '\0' があってもいいという点が,文字列と異なる.

ファイル操作のライブラリ関数(復習) 操作対象(関数への入力)は,ファイルポインタ. ライブラリ関数 stdio.h で定義されているFILE型のポインタ. 例: FILE *fp; ライブラリ関数 fopen : ファイルを開き(プログラムから使えるようにし),ファイルポインタを返す. fgets : 指定されたバイト数(文字数)を読み出す. fprintf : printfと同様の形式で,ファイルに出力する. fclose : 開いたファイルを閉じる(プログラムから使えないようにする). fgetc : 1バイト(1文字)読み出す.

行番号問題1 仕様 コマンドライン引数(複数ある場合は最初のみ)をファイル名とみなして,そのまま出力していく.ただし行の先頭には行番号をつける. 考え方 fgetcを用いて1バイトずつ読み出す. 「行の先頭」とは,「ファイルの先頭」か「改行文字('\n')の直後」のいずれか. 「今何行目を読んでいるか」を保存する変数line_countを用意する.

1文字ごとの読み出し(1) while ((c = fgetc(fp)) != EOF) {...} 'a' 'b' 'c' '\n' これがストリーム ファイルabc プログラムの 内部状態 'a' 'b' 'c' '\n' FILE オブジェ クト fp '\0'がない点に注意 (文字列ではない) c = ??? 'a'

1文字ごとの読み出し(2) while ((c = fgetc(fp)) != EOF) {...} 'a' 'b' 'c' '\n' プログラムの 内部状態 'a' 'b' 'c' '\n' FILE オブジェ クト fp c = ??? EOF '\n'

EOF(1) 「ファイルの終わり(End Of File)」を表す定数. stdio.hで,#define EOF (-1)などと定義されている. unsigned char signed char ASCII (7ビット) -128 -1 127 255 EOF ヌル 文字

EOF(2),ファイルアクセス 文字(バイト)単位で読み書きするとき 文字列単位で(何バイトか一括して)読み書きするとき int型を使用する. signed char型だと,255をEOFと区別できない. unsigned char型だと,EOFが来ても255にしてしまう. EOFから255までの「257種類の値」は,char型(signed char型,unsigned char型)で区別できない! 読み出してEOFが来たら,そこでおしまいにする. ライブラリ関数はfgetc, getcharなど 文字列単位で(何バイトか一括して)読み書きするとき char配列またはchar*型を使用する. ライブラリ関数はfgets, freadなど

標準入力と標準出力 標準入力(standard input, stdin) 標準出力(standard output, stdout) 通常はコンソール入力(キーボード入力) 標準出力(standard output, stdout) 通常はコンソール出力(画面表示) シェルのリダイレクション機能を用いて変更可能. 実行例: find ~ > files 実行例: ./liner < /usr/share/dict/words シェルのパイプ機能を用いて,あるプログラムの標準出力と別のプログラムの標準入力を接続できる. 実行例: echo '1+2*3' | bc

標準入力・標準出力とコンソール 実行環境 (OSなど) 標準入力 実行プログラム コンソール 'a' 'b' 'c' '\n' 'a' $ ./liner abc 1: abc $ 'a' 'b' 'c' '\n' '1' ':' ' ' 標準出力 実行コマンド 入力(エコーバック) 出力

標準入力に関するライブラリ関数 int getchar(void); char *gets(char *s); 標準入力から1文字(1バイト)読み込む. 戻り値はunsigned char型の値,もしくは定数EOF. char *gets(char *s); 標準入力から1行読み込み,sの指す領域に格納する. 1行が,sの領域サイズよりも大きいとしても,そのまま格納しようとする. int scanf(const char *format, ...); formatに従って標準入力から入力を読み込み,第2引数以降が参照する領域に格納する. 読み込みに失敗すれば,入力が進まない. なるべく使わない! なるべく使わない!

標準出力に関するライブラリ関数 int putchar(int c); char *puts(const char *s); cをunsigned char型に変換した上で,標準出力に(1文字)書き出す. char *puts(const char *s); 文字列sと改行文字を標準出力に書き出す. int printf(const char *format, ...); formatに従って標準出力に書き出す. 「標準出力に書き出す」の主語は,それぞれのライブラリ関数である. 「画面に表示する」ではない. ただし,「画面に表示される」というのは,利用するプログラマの観点とした表現であり,これは差支えない(利用する状況にも夜が). 「書き出す」「読み出す」はそれぞれ,「書き込む」「読み込む」と表現されることもある.

標準入出力と標準入出力関数 標準入力・標準出力に対する関数は,標準入出力関数およびstdin, stdoutを用いた関数形式マクロにより定義されている(ことがある). 例: #define getchar() getc(stdin)

行番号問題2 仕様 考え方 標準入力から入力をとり,そのまま標準出力に書き出す. ただし行の先頭には行番号を右揃えでつける. 読むのはgetchar(文字ごと),書くのはprintf(行ごと). すべての入力を終えた時点で,行数が確定し,そこから出力する. 入力内容を行単位で保存する. 標準入力は後戻りができない! 実行開始時に行数はわからないので, 「記憶域管理関数」を使用する. 「標準入力から入力し」と書いてはいけない. 一般に,入力「する」のはプログラムではないから. 一方,「出力する」と書くのは,その主語はプログラムなので,問題ない. ただし「標準出力に出力する」と表記すると,「出力」が2箇所出現してくどいので, 「標準出力に書き出す」とここでは書いた. なお,「画面に表示する」という表現がよく見られるが,これも,画面に表示「する」のは プログラムではないので,その意味では不適切であるが,古くから用いられ,また オンラインマニュアルの日本語訳でもよく見かけるので,「表示する」と書いて 試験で減点するようなことはしない.

liner.cの概要(1) 定義した構造体 定義した関数 line:1行の文字列の情報 line_array:行単位で分割した入力の情報 いずれも,「本体(具体的な中身,コンテンツ)」と「確保した要素数」と「格納されている要素数」をメンバに持つ. 定義した関数 get_line_array:入力を読み出す get_line:1行読み出す put_lines:行番号を付けて出力する get_digit_width:桁数を求める

liner.cの概要(2) 「右揃え」の出力方法 ライブラリ関数printfの補足 printf("%*d: ", width, i); iの値を,width文字分の右揃えで出力する. width=3, i=10なら," 10: "が出力される. 「*」を用いて,実行時に桁数を指定できる. ライブラリ関数printfの補足 様々な変換規則を持つ. 可変引数関数である. ファイルへ出力はfprintf, 文字列に書き出すのはsprintf

実行時の領域確保について プログラム実行時(main関数に制御が移る前)に ブロック({...})が実行されるときに static変数のオブジェクトが確保,初期化される. プログラム終了時に破棄される. ブロック({...})が実行されるときに auto変数のオブジェクトが確保される. ブロック終了時に破棄される. 記憶域管理関数(malloc, callocなど)を呼び出すと オブジェクトとして使用できる領域が確保される. freeなどの関数が呼び出されるか, プログラム終了時に破棄される. スタック領域 mallocは,リストやツリーのプログラムをCで書くときに必要になる. 例えば,ノード(節点)を自己参照構造体で定義し,新たなノードを作るときに,mallocなどでその構造体オブジェクトを生成するのである. ヒープ領域

mallocの基本的な使い方 準備 p = (int *)malloc(sizeof(int)); ⇒ *p がint型変数として利用可能. #include <stdlib.h> int *p; p = (int *)malloc(sizeof(int)); ⇒ *p がint型変数として利用可能. p = (int *)malloc(sizeof(int) * 10); ⇒ p[0], ..., p[9] がint型変数として利用可能. 必ずポインタ型 (intの部分は用途による) p p[0] p[1] p[9] … sizeof(int) *10 バイトの領域

malloc使用の注意点 領域の値は不定であるため,必要に応じて初期化する.代わりにcallocを使用すれば,すべて0に初期化された領域が得られる. 代入される変数はポインタ変数なので,左辺値になり得る(p++; などとできる). 領域確保に失敗するとNULLを返すので, if ((p = (int *)malloc(sizeof(int) * 10))        == NULL) { エラー処理 } などとするのが一般的.

可変長配列 可変長配列の例 可変長配列をCで取り扱うときは, 実行時にその個数(の上限)がわからないような配列 行番号問題2では,「1行の文字列」と「標準入力より獲得する入力(文字列の配列)」が該当する. 可変長配列をCで取り扱うときは, mallocまたはcallocで初期化し, より大きな領域が必要になったら,reallocを用いるとよい.

後始末 ファイルの読み書きを終えたら,fcloseを用いる. ヒープ領域の内容を解放するには,freeを用いる. 「fopen/fclose」をペアで覚える. fcloseを呼び出す前のファイルの出力内容は,プログラム内に保持されている(バッファリング)可能性がある. プログラム終了時に,閉じられていないファイルは保存されるが,これに頼らない(積極的にfcloseを用いる)ほうがよい. ヒープ領域の内容を解放するには,freeを用いる. 「malloc/free」をペアで覚える. プログラム終了時に,freeされていない領域も破棄される.基本的に,これに頼ってよい(積極的にはfreeを用いない).

まとめ ファイルは,実行プログラムとは異なる生存期間を持つ,バイト列のデータ構造である. ファイル,標準入力,標準出力にアクセスするためのさまざまな標準入出力関数が存在する. 実行後のオブジェクト確保には,mallocなどを用いる. 後始末を忘れずに.

プログラミング講義を終えて(1) 授業内容の関連 難しかったテーマを復習するときは,関連する(一つ前や後の)テーマを見直すのもよい. 構造体 入出力 ライブラリ関数 再帰呼び出し その他の型 前処理指令 関数 変数の有効範囲 (新設) 記憶域管理関数 (名称変更) 算術型⇒算術型・型変換 ファイル入出力⇒入出力 制御文 演算子 ポインタ 記憶域管理関数 識別子 算術型・型変換 配列・文字列

プログラミング講義を終えて(2) 2年以降で身につけてほしいこと 自在にCでプログラミングできる能力 特に,ファイル処理,文字列処理,リストとツリー,スタックとキュー 「先人の知恵」を学び活用する能力 ライブラリ関数,先生・先輩のノウハウ プログラムを設計する能力 与えられた課題に対して,何をすべきかを自主的に決め,プログラムコードや文章で表現すること

今後の日程 1月31日(水):金曜の授業だが,当科目は実施しない. 2月2日(金):おさらい問題 2月9日(金):試験 11月8日に補講実施済のため. 2月2日(金):おさらい問題 何でも持ち込み可.相談可.成績には関係ない. 5分復習問題,40分おさらい問題,45分解説 2月9日(金):試験 80点満点 自筆ノート1冊と,C言語の教科書1冊の持込可