プログラミング作法と デバッグ ― VC++ 編 ―
プログラミング作法 字下げ(インデント) 注釈(コメント) 初心者 名前のつけ方 モジュラー化 非対話化 配列の動的確保 注釈(コメント) 初心者 名前のつけ方 モジュラー化 非対話化 フィルタ(リダイレクト、パイプ) 中級者 コマンドラインオプション 配列の動的確保
字下げ(インデント) 対等な関係にある文は同じ桁位置に 制御文(if文, case文, while文, do文, for文)の内部の単文は字下げ(2文字分) { と } の内部も字下げ(2文字分) Tabキーは使わない(タブ数=8に) オートインデントは使わない 他のエディタでの印刷時に不揃いの可能性
注釈(コメント) // は一行コメントに /* … */ は複数行コメントに → 無効化 日本語(または英語)でわかりやすく /* … */ は複数行コメントに → 無効化 日本語(または英語)でわかりやすく プログラムや関数のはじめに 目的、内容、参考文献 前提条件、制限事項 作成日時、作成者 プログラムや関数の最後に //プログラム名、//関数名 「今日の自分は、明日の他人」
名前のつけ方 役割を反映する簡潔な名前をつける ローマ字は避け、英語にする 広範囲に使う名前は長く、局所で使う名前は短く 長い名前を短くする方法 最初の数個の文字 int, str, info, sci, com 母音を省略 msg, ctrl, cnt, chg, ltd
名前のつけ方(その2) 大文字と小文字をうまく使い分ける 2つ以上の単語の区切りは明確化 型によって使う文字を決める ユーザ定義定数は大文字で始める Pi, Epsilon ユーザ定義データ型は大文字で始める Point, Vector 汎用変数は小文字で始める 2つ以上の単語の区切りは明確化 threeWordName 型によって使う文字を決める 整数型の添え字は i, j, k,… 整数型の定数は N, M, L を含める MaxN 状態(論理変数)はis+大文字始まり isEven, isPrime
デバッグのコツ コンパイラ・メッセージの利用 ランタイム・エラーとその原因 よくやるミス 見つけにくいバグ
コンパイラ・メッセージ コンパイル情報 ファイル名(行, 桁): メッセージコード: 内容 コンパイル結果情報 error: エラー warning: 警告 コンパイル結果情報 /out:???.exe: 実行形式ファイル ???.obj: オブジェクトファイル
頻度の高いエラー・メッセージ 以下のエラーの意味をよく理解しておく 構文エラー 定義されていない識別子です。 文字 ‘0x81’ は認識できません。 再定義されています。 関数には戻り値が必要です。 実引数が少なすぎます。 互換性のない型が含まれています。
ランタイム・エラー 制限オーバー スタック・オーバーフロー ハングアップ → [Ctrl-c] で強制終了 対策: 途中経過を報告させる 0で除算、負の平方根・対数 オーバーフロー、アンダーフロー スタック・オーバーフロー 再帰的定義など ハングアップ → [Ctrl-c] で強制終了 無限ループなど 対策: 途中経過を報告させる どこまで正常に終わったかを出力 あやしい変数の値を出力
よくやるミス スペルミス 変数の宣言忘れ カッコのとじ忘れ セミコロンのつけ忘れ 文字列のシングルクォートとコンマ 予約語、宣言済み名前との競合 ソースファイル名の異常 コンパイル時の自動保存による失敗
見つけにくいバグ セミコロン 2バイト(全角)文字の混入 コメントの入れ子 while (式); 文; スペース(空白) コンマ、カッコ、 、 、 … コメントの入れ子 /* /* */ */ → /* // */ ; : ’
字下げとフォントの設定 devenv(Visual Studio のエディタ)において「ツール」→「オプション」→「テキストエディタ」→「C/C++」で「タブサイズ」、「インデントサイズ」をおのおの4にセットし、「空白の挿入」欄をチェックする。 Tabキーを時々、使いながらプログラムソースを入力。 ファイル名を ???.c として保存する。 Word(Notepad)で表示(印刷)してインデントの乱れがないか、確認する。 Wordの場合はMS ゴシックなどの等幅フォントを指定する。MS PゴシックなどPがつくフォントにはしないこと。 欧文フォントでは Courier New を用いるとよい。
デバッグの練習1 /* while の無限ループの練習 */ int main(void) { int a; printf("整数を入力 > "); scanf("%d", &a); while (a > 0); a = a - 1; printf("%4d\n", a); } } // while.c
デバッグの練習2 /* ランタイム・エラーの練習 */ #include <stdio.h> #define PI 3.141592 int main(void) { double x; x = sqrt(PI); printf("sqrt(PI) = %f\n", x); x = sqrt(-PI); printf("sqrt(-PI) = %f\n", x); } // sqrt.c
オプション問題 以下のプログラムを実行し、整数を入力したら、途中停止せずに終わってしまった。どこを直せばよいか。 /* 途中停止の練習 */ int main(void) { int i; char c; printf("整数を入力 > "); scanf("%d", &i); printf("i = %d\n", i); printf("リターンキーを押してください."); c = getchar(); }