10.3K Views
July 14, 22
スライド概要
津山高専情報工学科のプログラミングの講義で使用した古い資料です.コードを書くときの注意点をまとめてあります.
読みやすいコードを書くために 藤田 一寿 20171206
プログラミングでは何が重要か? 才能も必要かもしれませんがもっと重要なものが あります。
プログラミングで大切なこと それは可読性の高いソースコード を書くことです!!
可読性の高いソースコードの必要性 ‣ 読みにくいコードは、書いているうちにそのコードがど のような処理をしているか分からなくなることがありま す。 ‣ 例えば、インデントがむちゃくちゃなコードの処理を理解 しようとすると大変ですね。 ‣ 読みにくいコードはコードの処理を理解することが難 しいため、コードの間違いに気づきにくくなります。 ‣ 間違いに気づかないため、間違ったコードが残ったま まになり、動作不良のソフトウェアが世に出るかもし れません。
可読性の高いソースコードの必要性 ‣ ソースコードは1度書いたら放ったらかしになることは ありません(授業ではレポートを書いたら終わりかもしれ ませんが)。 ‣ メンテナンスの必要があります。 ‣ 機能を拡張させる必要があるかもしれません。 ‣ 誰がメンテナンスしても良いように、読みやすいコードを 書く必要があります。 ‣ また、長期間放置された可読性の低いコードは、コードを 書いた本人もその処理を理解できない可能性があります。 結果,書いた本人すらメンテナンスできなくなってしまい ます.
可読性の高いコードとは ‣ コメントが付いている。 ‣ マジックナンバーがない。 ‣ 意味のある変数名が付けてある。 ‣ 変数は使用する直前または近くで宣言する。 ‣ インデントがプログラムの構造と合っている。 ‣ 制御構造を中括弧で表すものには、省略できる場合でも中括弧を省略 していない(反対意見あり)。 ‣ トリッキーなコードを書いていない。 ‣ コーディング規則を守っている。
コメントを付ける ‣ 演習程度の短いコードでは、コメントを付けなくても何 をやっているかわかります。 ‣ しかし、長いコードでは変数の意味や関数の意味がわか らなくなることがあります。 ‣ それを避けるためにコメントを付ける必要があります。 ‣ また、他人が見てもすぐ分かるようにするためにも必要 です。 分かりやすい表現を用いていれば必要ないことも多いですが
例 const int XMAX = 800; //画面の縦幅 const int YMAX = 600; //画面の横幅 int sum(int num) 変数が何の値を意味するか,コメントにより { 分かります。 /* * 0から引数numまでの整数の総和を計算し、 * その値を返す。 */ 関数がどのような処理をするかコメントによ り分かります。
マジックナンバーをなくす ‣ マジックナンバーがあると、定数の意味がわからない どころか、バグ発生する原因になります。
マジックナンバーとは ‣ 定数が直接数字書かれているものです。 for(int i = 0; i < 10; i++){ ただ10というだけでは意味不明です。 何か意味がある定数のはず。
マジックナンバーをなくす for(int i = 0; i < 10; i++){ const int NUM = 10; //配列の個数 for(int i = 0; i < NUM; i++){
マジックナンバーをなくすと ‣ 定数の意味が明示される。 ‣ ソースコードの様々な場所で使われる定数が、一度に 全て変更できる。 ‣ 変更漏れがなくなり、バグが減る。 ‣ 1箇所変更するだけで済むので、楽ができる。
意味のない変数名 int a = 10; int b = 0; for(int i = 0; i < a; i++){ b += i; } この例では短いコードなので、意味が無い変数名でもわ かりますが、1万行のソースの中でaとかbが頻出すると 困りますね。
意味のある名前 const int MAX = 10; int sum = 0; for(int i = 0; i < MAX; i++){ sum += i; } ‣ ‣ 意味のある変数名にすると、変数の利用方法が分かりや すくなりバグが減ります。 aとかbを多用していると、バグの原因になります。 ‣ どのaがどのように使われるかわからないため。
ハンガリアン記法 ‣ 変数名を変数の種類が分かるようなものにする。 ‣ システムハンガリアン記法 ‣ ‣ 変数型が分かるように、変数の頭にプレフィックスをつ ける。 アプリケーションハンガリアン記法 ‣ 変数の意味が分かるように、変数の頭にプレフィックス をつける。 ‣ minX, maxY, usName, yenX, usdX
システムハンガリアン記法の例 ‣ 変数型を表すプレフィックス+変数名 ‣ ‣ ‣ int iX; 整数型 iFoo 単精度浮動小数型 fBar 倍精度浮動小数 dHoge 論理型 bFooBar ポインタ pHogehoge double fX; char sX;
‣ ‣ システムハンガリアン記法は辞める方向になっている。 ‣ よくわからない記号が多くなり可読性が悪い。 ‣ 型が変わった時、いちいち変数名を変えなければならない。 ‣ 現在マイクロソフトも推奨していない。 ‣ そもそも必要ない。 アプリケーションハンガリアンの考え方はいまでも有効。
キャメルケース ‣ 変数名に複数の単語を使うとき、そのまま並べたのでは意味がわから なくなります。そこで、単語の区切りがわかりやすくするために,キ ャメルケースという記法があります。 ‣ Upper camel case ‣ ‣ 単語の区切りが分かるように,単語の先頭の文字を大文字にする。 ‣ 例: CamelCase lower camel case ‣ 単語の区切りが分かるように、単語の先頭の文字を大文字にする。ただ し、先頭の単語の先頭の文字のみ小文字にする。 ‣ 例:camelCase
スネークケース ‣ 複数の単語を変数名で使うとき、単語の区切りが分か るよう単語と単語の間にアンダースコア(_)を入れ るやり方をスネークケースといいます。 ‣ 例:snake̲case
変数宣言の場所 ‣ 変数宣言は変数を使う場所の近く(直前)に行う。 ‣ 昔々のC言語の仕様のため、古い人はプログラムの先頭 で宣言しますが、いまは変数を使用する場所の近くで 宣言することが一般的です。 ‣ 関連するものは近づける、使用範囲は狭くという思想 です。
インデントの重要性 ‣ プログラミングを行うときに最も重要な事が、インデン トを正確にすることです。 ‣ プログラマはインデントを頼りに、プログラムの構造を 理解しようとします。 ‣ インデントが無茶苦茶だと、プログラムの理解を妨げる。 ‣ 結果、バグが増える。 ‣ 保守をやりにくくなる。
悪いインデント int main(void){ for(int i = 0; i < 10; i++){ print(“%d\n”, i); } return(0); } 学生の書くソースコードでよく見ます。 プログラムの構造とインデントが一致しておらず、 間違いを発見するのも容易ではありません。
良いインデント int main(void) { for(int i = 0; i < 10; i++){ print(“%d\n”, i); } return(0); } プログラムの構造とインデントが一致しており、プ ログラムの構造が分かりやすくなっています。
トリッキーなコードを書かない ‣ なるべくよく使われる表現を使う。 ‣ よく使われる表現を用いることで、誰にでも分かるソ ースコードになる。
コーディングスタイル ‣ コードの見た目を統一し、混乱をさせないために必要。 ‣ コードを分かりやすくする。
代表的なコーディングスタイル ‣ K&Rスタイル ‣ カーニハンとリッチー(K&R)が書いたC言語の本で使わ れているスタイル ‣ Linuxスタイル ‣ BSDスタイル ‣ GNUスタイル
例 int main(void) {//メイン関数 for(int i; i < 10; i++){//10回テストを表示 printf(“test\n”); } return(0); } インデントはスペース4つ 関数のカッコは改行後に 制御文のカッコはその直後に 本当は見てすぐ分かるようなことはコメントで書かないよ。
メンテナンスしやすいコードを書くために ‣ 可読性の高いコードを書く。 ‣ 長い関数を書かない。 ‣ ‣ 機能は細分化する。 ‣ 機能毎に変更がしやすい。 一つのファイルに、長いプログラムを書かない。 ‣ 機能毎にソースコードを分ける。 ‣ クラスをうまく使う。 ‣ 標準で用意されている関数やライブラリを有効に使う。 ‣ 独自実装はバグのもと。
注意 ‣ ‣ この講義で述べたことは大方の人が納得するように書い てありますが、絶対正しいとはいえません。 ‣ プログラミングの作法、コーディングルールは、プログラ マなら一家言あり、それぞれ正しいが異なっていることが あります。 ‣ 会社ごと、部署ごとにルールがあります。 ‣ 時代が変われば、正しいことも変わります。 少なくとも、自分のルールを持ってプログラミングをし ましょう。
参考書 CODE COMPLETE スティーブ マコネル プログラミング作法 ブライアン カーニハン, ロブ パイク 「間違ったコードは間違って見えるようにする」というwebサイトも参考になります。