情報処理Ⅱ 第10回:2004年1月13日(火) 本日のテーマ 標準入出力 記憶域管理関数 標準入力と標準出力 いくつかの標準入出力関数 malloc, freeなど 実行時に配列領域を確保する手法 落ち穂拾い 入力の与え方 コメントの書き方 制御文 知っておくべき「C言語の文法」 問題(授業がつまらない人のため に) ファイルを入力にとり,その中で最も長い行を出力 せよ. 最も長い行 = バイト数が最も多い行 複数ある場合は最初の一つのみ出力する. 標準入力に入力されたデータの中で,最も長い行を 出力せよ. 落ち穂拾い1:入力の与え方 プログラム内に書き込む. コマンドライン引数から獲得する. int main(int argc, char *argv[ ]) 標準入力(キーボード入力)から獲得する. int a = 44, b = 16; scanfを用いる. getcharやfgetsなどを用いる. ファイルをアクセスする. fopen, freadなどを用いる. メリットとデメリット 入力の与え方:得失(1) プログラム内に書き込む(埋め込む). ハードコーティングとも呼ばれる. 手軽(原始的)であり,他の環境でも実行しやすい. 入力の値の型は,プログラム内で指定できる. 入力の値が変わるたびにコンパイルが必要. コマンドライン引数から獲得する. 入力の値が変わってもコンパイル不要. 実行時に毎回引数指定が必要.ただしシェルのヒス トリ機能を使えば省力化できる. 入力サイズには(現実的な)制限がある. 入力の値の型は必ず文字列. 入力の与え方:得失(2) 標準入力から獲得する. 入力の値が変わってもコンパイル不要. 入力サイズに制限がない. 実行時に毎回入力が必要.ただしシェルのリダイレ クション機能を使えば省力化できる. 入力の値の型は原則として文字または文字列. ファイルをアクセスする. 最も洗練された手法. 標準入力の特長を受け継ぐ. ファイルの内容を変えなければ,同じ入力が得られ る. プログラムは複雑になる. 入力の与え方:比較 洗練 柔軟 コマンドライン引数 ファイルアクセス 標準入力 静的 動的 (main関数実行前に 入力値が決まる) 埋め込み (実行中に入力値を 与える) 原始的 固定 標準入力と標準出力 標準入力(standard input, stdin) 標準出力(standard output, stdout) 通常はコンソール出力(画面表示) シェルのリダイレクション機能を用いて変更可能. 通常はコンソール入力(キーボード入力) 実行例: find > files 実行例: patch -p0 < patch-2.4.20 シェルのパイプ機能を用いて,あるプログラムの標 準出力と別のプログラムの標準入力を接続できる. 実行例: echo '1+2*3' | bc 例題1 標準入力から入力を受け取り,各行の先頭に行番号 をつけて標準出力に出力する. 標準入力・標準出力とコンソール 標準入力 実行環境 (OSなど) コンソール a b c \n ... 実行プログラム 1 : a b c \n ... 標準出力 実行コマンド 入力(エコーバック) 出力 は1バイト 標準入力に関するライブラリ関数 int getchar(void); char *gets(char *s); 標準入力から1文字(1バイト)読み込む. 戻り値はunsigned char型の値,もしくは定数EOF. 標準入力から1行読み込み,sの指す領域に格納する. 1行が,sの領域サイズよりも大きいとしても,その まま格納しようとする. int scanf(const char *format, ...); なるべく使わない! なるべく使わない! formatに従って標準入力から入力を読み込み,第2引 数以降が参照する領域に格納する. 読み込みに失敗すれば,入力が進まない. 標準出力に関するライブラリ関数 int putchar(int c); char *puts(const char *s); cをunsigned charに変換した上で,標準出力に(1文 字)出力する. 文字列sと改行文字を標準出力に出力する. int printf(const char *format, ...); formatに従って標準出力に出力する. 例題2 標準入力から入力を受け取り,最も長い行を出力す る. ただし,255バイト以上の行には対処できない. 対策 「1行は255バイトまで」を仕様にする. 配列に格納できる字数を大きくする. 配列領域を実行時に確保する. 実行時の領域確保について プログラム実行時(main関数に制御が移る前)に static変数のオブジェクトが確保,初期化される. ブロックが実行されるときに スタック領域を 用いる. auto変数のオブジェクトが確保される. プログラム終了時に破棄される. ブロック終了時に破棄される. 記憶域管理関数(malloc, callocなど)を呼び出すと オブジェクトとして使用できる領域が確保される. freeなどの関数が呼び出されるか,プログラム終了時に 破棄される. ヒープ領域を 用いる. mallocの基本的な使い方 準備 #include <stdlib.h> int *p; p = (int *)malloc(sizeof(int)); とすると,*p がint型変数として利用可能. p = (int *)malloc(sizeof(int) * 10); とすると,p[0], ..., p[9] がint型変数として利用可能. p p[0] p[1] … p[9] sizeof(int) *10 バイトの領域 malloc使用の注意点 領域の値は不定であるため,必要に応じて初期化す る.代わりにcallocを使用すれば,すべて0に初期 化された領域が得られる. pはポインタ変数なので,左辺値になり得る(p++; などとできる). 領域確保に失敗するとNULLを返すので, if ((p = (int *)malloc(sizeof(int) * 10)) == NULL) { エラー処理 } などとするのが一般的. 例題3(例題2の改良) 標準入力から入力を受け取り,最も長い行を出力す る. 1行のバイト数制限をなくす. ついでに,入力に '\0' があっても適切に処理するよ うにする. (一般的な)標準入出力関数 操作対象(関数への入力)は,ファイルポインタ. stdio.h で定義されている「ファイル構造体」のポイ ンタ. 型はFILE * 標準入力・標準出力に対する関数は,標準入出力関 数およびstdin, stdoutを用いた関数形式マクロによ り定義されている(ことが多い). 例: #define getchar( ) getc(stdin) 引数なしの関数形式マクロ (voidを書かない) 落ち穂拾い2:コメントの書き方 コメント(注釈)の書き方 書くべき箇所 /* … */ // … #if 0 … #endif 複数行可.入れ子にできない. 行末まで.最近の規格で認められた. 行単位.入れ子にできる.本来の使い方 ではないので,「清書」では書かない. ファイルの先頭: ファイル名,作成者,作成日時など 関数定義の直前: 機能,入出力など 型,変数,定数などを定義する行: 意味・役割など 留意すべきプログラムコードの近辺: 処理内容 書いてはいけない プログラムコードを見れば明らかな処理内容 落ち穂拾い3:制御文(1) if (条件) 処理; と if (条件) {処理;} は,「処理」が (文法的に,一つの)文であれば,同じ.常に後者 の書式を用いるプログラマも多い. else, while, for にも当てはまる. ifと,真のときに実行する文やelseとの対応に注意. if (条件) 処理1; 処理2; if (条件) { 処理1; 処理2; } 違う! 条件の真偽にかかわらず 処理2を実行する. if (条件1) if (条件2) 処理1; else 処理2; if (条件1) { if (条件2) 処理1; } else 処理2; 違う! 条件1が真,条件2が偽のとき に限り,処理2を実行する. 落ち穂拾い3:制御文(2) whileやforのループ中に 無限ループの決まり文句 breakがあれば,そこでループを抜ける. continueがあれば,それ以降の処理を行わずに条件判 定に戻る(forループでは増分処理を行う). while (1) { 処理 } for (;;) { 処理 } 通常,処理の中にbreakを置き,何らか の条件でループから抜けるように書く. 空文を使ったループ while (代入および条件判定); for (初期化; 条件判定; 増分処理); セミコロンの前で改 行する(セミコロン のみの行を作る)書 法もある. 知っておくべき「C言語の文法」 型 制御文 算術型,ポインタ型,関数型,構造体(struct)と共用 体(union),typedef,列挙型(enum) if, while, for, do~while, switch~case return, break, continue 配列とポインタ 演算子および式評価 識別子(変数,関数,ラベル) 前処理指令 青線部: 主な出題範囲 今後の予定 1月20日(火):おさらい 1月27日(火):試験 2月3日(火) :補講.プログラミング能率向上 のノウハウについて(採点対象外) 試験について 日時:1月27日(火) 14:50~16:20 場所:A203 以下の2点の持ち込みを認める. C言語に関する書籍 1冊 自筆ノート1冊,もしくは,シート1枚 ルーズリーフも許可するが,常にバインダに綴じておき, シートを取り出さないこと(カンニング防止のため) 持ち込み不可のもの 計算機類(電卓,ノートPCなど) 2枚以上のシート(カンニング防止のため.ステー プラなどで綴じていても不可とする.) シートなどを貼り付けた書籍やノート 発展的な話題: なぜscanfはいけ ないのか http://www.cda.ics.saitamau.ac.jp/~maekawa/lect/C/file-io.html が詳しい. while (scanf(…) != EOF) は厳禁! 変換に失敗すれば,無限ループになる. 代替案: while (scanf(…) == 変換の個数) 変換に失敗すれば,そこでwhileループを抜ける. fgetsで文字列領域に格納し,sscanfで変換する. 変換に失敗しても,その入力だけを読み飛ばせる.
© Copyright 2024 ExpyDoc