プログラミング作法
TRANSCRIPT
![Page 1: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/1.jpg)
プログラミング作法分かりやすいソースコード
beatle
13年3月16日土曜日
![Page 2: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/2.jpg)
自己紹介
• mixC++では2011年冬から活動
• C++/C#が好き
• プログラミング教育の研究
13年3月16日土曜日
![Page 3: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/3.jpg)
プログラミング作法
• ブライアン・カーニハン
• 当たり前だが重要なこと
• 可読性・保守性
13年3月16日土曜日
![Page 4: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/4.jpg)
メニュー
• 命名
• スタイル
• コメント
• 移植性
13年3月16日土曜日
![Page 5: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/5.jpg)
命名
• 「プログラミングは『名前』が9割。」あるブログより
• 良い名前 ≒ 良いプログラム
13年3月16日土曜日
![Page 6: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/6.jpg)
命名規則
• 全体で統一する
• ルールの内容自体は重要でない
• PascalCasecamelCasesnake_case
13年3月16日土曜日
![Page 7: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/7.jpg)
変数名
• 長く、説明的な名前
• 短く、簡潔な名前
// 現在の入力キューの長さint npending = 0;
for (i = 0; i < nelems; i++)
for (theElementIndex = 0; theElementIndex < numberOfElements; theElementIndex++)
グローバル変数
ローカル変数
13年3月16日土曜日
![Page 8: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/8.jpg)
関数名• 「動詞+名詞」が基本
• putchar
• getTime
• 真偽値を返す関数if (check_digit(c)) ...
if (is_digit(c)) ...
13年3月16日土曜日
![Page 9: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/9.jpg)
スタイル
• 全体で統一する
• ルールの内容自体は重要でない
• K&RBSD/AllmanGNU
13年3月16日土曜日
![Page 10: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/10.jpg)
自然な形の式
• 音読するつもりで書く
• 否定は分かりにくいif (!(block_id < actblks) || !(block_id >= unblocks)) ...
if ((block_id >= actblks) || (block_id < unblocks)) ...
13年3月16日土曜日
![Page 11: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/11.jpg)
かっこを使おう
• 演算子の優先順位は分かりにくい
• 本来不要な場所にも付けるleap_year = y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
leap_year = ((y%4 == 0) && (y%100 != 0)) || (y%400 == 0);
13年3月16日土曜日
![Page 12: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/12.jpg)
慣用句と一貫性i = 0;while (i <= n-1) array[i++] = 1.0;
for (i = n; --i >= 0; ) array[i] = 1.0;
for (i = 0; i < n; i++) array[i] = 1.0; ループの慣用句!
13年3月16日土曜日
![Page 13: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/13.jpg)
慣用句と一貫性• 他にも様々な慣用句がある
• リストのトラバース
• 無限ループfor (;;)while (1)
for (p = list; p != NULL; p = p->next)
13年3月16日土曜日
![Page 14: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/14.jpg)
悪いコメント1
• 当たり前のことはいちいち書くな/* SUCCESS を返す */return SUCCESS;
/* ゼロエントリカウンタをインクリメント */zerocount++;
13年3月16日土曜日
![Page 15: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/15.jpg)
悪いコメント2
• 悪いコードにコメントをつけるな/* "result"が0ならマッチするものが見つかったので真を返す そうでなければ"result"はゼロ以外なので偽を返す */
printf("*** isword returns !result = %d\n", !result);return(!result);
printf("*** isword returns matchfound = %d\n", matchfound);return matchfound;
コメント > コードなら怪しい
13年3月16日土曜日
![Page 16: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/16.jpg)
悪いコメントその他
• コードと矛盾したコメント
• 読者の混乱を増大させるコメント
13年3月16日土曜日
![Page 17: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/17.jpg)
良いコメント1
• グローバルデータにコメント
• 必要に応じて参照されるメモ
struct Status { /* プレフィクス+サフィックスリスト */ char *pref[NPREF]; /* プレフィクス用の単語 */ Suffix *suf; /* サフィックスのリスト */ State *next; /* ハッシュテーブル中の次の項目 */};
13年3月16日土曜日
![Page 18: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/18.jpg)
良いコメント2
• 関数にコメント
• 関数が全体として何をするか
// random: [0..r-1]の範囲の整数を返すint random(int r){ return (int)(Math.floor(Math.random()*r));}
13年3月16日土曜日
![Page 19: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/19.jpg)
移植性• 自分の環境だけで動けばいい?
• 自分の環境だって変わる!
• 移植性向上の労力 →優れたプログラミング
13年3月16日土曜日
![Page 20: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/20.jpg)
標準に固執する
• 言語の標準に従う
• ANSI-C, C99, C++11 ...
• 標準ライブラリを使う
• stdio.h, iostream, STL ...
13年3月16日土曜日
![Page 21: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/21.jpg)
条件コンパイル• 条件コンパイルは避けよう
• 全組合せでテストできますか?
#ifdef _MAC printf("This is Macintosh\r");#else ほかのシステムではこの文で構文エラー#endif
13年3月16日土曜日
![Page 22: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/22.jpg)
まとめ
• 命名:説明的な名前 vs 簡単な名前
• スタイル:慣用句で見やすく!
• コメント:整合性を意識
• 移植性:良いプログラムへの道
13年3月16日土曜日
![Page 23: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/23.jpg)
命名するということ
• 名前を付ける=抽象化=プログラミング
• 例えば、配列のコピー
13年3月16日土曜日
![Page 24: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/24.jpg)
int main(void){ char buf[16], data[N]; int block = 0, i; ...
// 16バイトずつ読み込んで、dataに格納 while (1) { fread(buf, 1, sizeof(buf), fp); if (feof(fp)) break; for (i = 0; i < sizeof(buf); i++) data[block * sizeof(buf) + i] = buf[i]; block++; }}
処理を埋め込む
13年3月16日土曜日
![Page 25: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/25.jpg)
関数に分けるint main(void){ char buf[16], data[N]; int block = 0, i; ...
// 16バイトずつ読み込んで、dataに格納 while (1) { fread(buf, 1, sizeof(buf), fp); if (feof(fp)) break; copy_array(data + block * sizeof(buf), buf, sizeof(buf)); block++; }}
13年3月16日土曜日
![Page 26: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/26.jpg)
// 16バイトずつ読み込んで、dataに格納while (1) { fread(buf, 1, sizeof(buf), fp); if (feof(fp)) break; copy_array(data + block * sizeof(buf), buf, sizeof(buf)); block++;}
// 16バイトずつ読み込んで、dataに格納while (1) { fread(buf, 1, sizeof(buf), fp); if (feof(fp)) break; for (i = 0; i < sizeof(buf); i++) data[block * sizeof(buf) + i] = buf[i]; block++;} 抽象化
13年3月16日土曜日
![Page 27: プログラミング作法](https://reader030.vdocuments.site/reader030/viewer/2022020306/556a7663d8b42a7c758b479a/html5/thumbnails/27.jpg)
ご清聴ありがとうございました
ラベル付けは大事!!
13年3月16日土曜日