プログラミング > ダメ。ゼッタイ。


概要

糞コードの乱用は国民の生命、身体に危害を及ぼすのみならず、家庭を崩壊させ、学校、職場、サークルの秩序を乱し、国の活力を低下させる等、その害悪ははかり知れません。 また、糞コード乱用は、人類にとっても、最も深刻な社会問題でもあります。世界的には、次代を担う青少年の糞コード乱用が増大しております。

糞コード乱用に対する正しい知識の普及、つまり、糞コード乱用が精神、身体に及ぼす悪影響を国民によく理解していただき、これを許さない国民世論を形成していくことがなにより大切であります。

このような観点から、閣議の了承を踏まえて、民間団体(財団法人糞コード乱用防止センター)が設立され、糞コード乱用防止活動を国民運動として、糞コード乱用を許さない「ダメ。ゼッタイ。」の社会環境づくりを実施することを推進しております。

このページは、糞コードの例を提示し、それによる被害を把握することで同じ過ちを犯さないようにすることを目的としています。

糞コードの例

軽度の被害が想定される。修正は容易である。
☆☆
中度の被害が想定される。修正に時間がかかるが、なんとかなる。
☆☆☆
重度の被害が想定される。もはや誰も手を付けられない。

☆インデントがされていない

インデントとは、ソースコードで意味のあるまとまりを字下げすることで、その意味のあるまとまりをわかりやすくするための技法のことです。

意味のあるまとまりとしては{から}の中、が有名です。以下は妥当なインデントの例です。

if(a) {
	// これがインデント
	switch(b) {
	case 10: // caseはインデントしない場合が多い
		func(); // これもインデント
		break;
	default:
		break;
	}
}

だめな例は以下の通りです。

if(a) {
// これがインデント
switch(b) {
case 10: // caseはインデントしない場合が多い
func(); // これもインデント
break;
default:
break;
}
}

インデントがされていないソースは、そのソースが何を意図されて書かれたのか分からなくなることが多くあります。インデントをすることで、そのブロックがすべきことを明確にします。逆に、インデントがされていないソースを書いている本人は、頭の中に構造が浮かんでいないことでしょう。

関連:☆「メモ帳」でソースを書いている

メモ帳には、オートインデント機能がありません。オートインデント機能とは、改行したときに、その行のインデントを引き継ぎ、自動的にインデントをした状態で次の行を生成する機能です。このため、インデントを怠るケースが想定されます。

対処法としては、オートインデントを実装するテキストエディタに乗り換えること、推奨される対処法としては、IDEを使うことが挙げられます。

☆☆☆グローバル変数が多用されている

グローバル変数が多用されることは、ローカル変数なら1つの関数の中だけ把握すればいいのに対して、グローバル変数だとファイル全体を見なければならないことからあってはならないことです。グローバル変数とは、関数の中で宣言しないで、関数外で宣言された変数のことです。

以下の例では一体a, b, c, dはどこまで影響を及ぼすのでしょう。

int a, b, c;
int d[10];

void f1(int n) {
	a = b + c;
	d[n] = a;
}
void f2(int x) {
	b = c - x;
}
void f3(int n) {
	a = b;
	d[n] = a;
}
void f4(int x, int y) {
	b = x;
	c = x + y + a;
}

対処法としては、グローバル変数は一切使わない、というものがあります。特に初心者は心がけるべきで、最初は不便だと思うくらいがちょうどいいです。グローバル変数がどうしても必要なケースに遭遇したら、よく考えた上で、ファイルスコープ上でstaticを付けて宣言して下さい。そうすれば1つのファイルの中でのみ使えるグローバル変数となります。

C++をかじったことのあるひとなら、C言語で言うファイルスコープ上のstaticな変数は、クラスで言うstaticな変数と同じです。クラスの中でしか使えない、ファイルの中でしか使えない、という意味で同じです。

もう一度言いますが、グローバル変数を使うのは禁じ手です。使う必要性をA4レポート1枚にまとめられるくらいになったら使ってもいいレベルで禁じ手です。禁じ手と言うよりも滅びの呪文だと思って下さい。バルス

☆☆変数の名前が1文字

変数の名前は重要です。変数の名前が適当でいいという人は機械語でも直接書いていて下さい。変数は意味のある名前にすべきで、例外は余りありません。長いと思うくらいがちょうど良いのです。

気軽にa, b, c, ...などと名付けてはいけません。使っていいのは、明らかに分かる場合のみです。明らかに分かる場合とは、以下の例くらいでしょう。

1重のループカウンタ

慣習的に使われているループカウンタiです。これはindexの略として捉えられ、十分通じますし、逆に長い名前を付けることもないでしょう。

for(i = 0; i < n; ++i) {
	// loop
}

ただし、2重ループではほとんどの場合不可です。大丈夫なケースはi, jを交換しても同じ動作をするときのみです。

for(i = 0; i < m; ++i) {
	for(j = 0; j < n; ++j) {
		// loop
	}
}

例えば、i, jが座標なら、どの方向の座標なのか分かるように、x, yにしたり行/列ならrow(r), columun(c)にするなど工夫するべきです。

イテレータ

C++などイテレータを使う場合は、そのオブジェクトが分かるのでitなど略しても構わないでしょう。

慣用される1文字変数

x, y, zなどが特定の方向の座標を表すのは、数学に理解のある人なら当たり前のことでしょう。

個数

ループと被りますが、m, nなどが自然数の個数を表すことはわかるでしょう。ただし2つ以上混在する場合は、明確にするべきです。m1, m2, ...などと名前を付けてはいけません。

一時的な変数

スコープが非常に狭い変数では、一時的な作業用の変数としてtemp、tなど用いても構わないでしょう。ただし、その変数は1画面に収まる内に消え去るべきです。temp_を先頭に付けることを推奨します。

コーディング規約

このような糞コードを量産しないために、プログラマーに縛りを課して糞コードを増やさない試みがなされています。このような縛りをコーディング規約と言います。

コーディングの好み

コーディングには好みが現れます。例えば、変数名の付け方、インデントのスペース/Tab、{ }の位置、スペースの挿入の好み、returnなどの使い方、制御構文の使い分け、クラスの継承/包含の選択、I/Fの実装の仕方……おそらくたくさんの好みがあると思います。あなたの好みをここにまとめてみましょう。

インデント

  • スペースインデント
    • どの環境でも同じようにインデントされる
  • タブインデント
    • 1インデントにつき1文字だから、多くの環境でBackSpace=逆インデントとなって効率が良い
    • 貧弱な環境でもインデントがきれいに揃う

演算子の前後のスペース

  • 常に入れる
  • 入れない場合がある
    • 例えば3分の2を表現するなら2/3で2 / 3としないなど。
    • 優先順位の高い演算子にはスペースを入れないなど。

{~}の表現

新しい行を使う派

if()
{ // 新しい行を使う
	
}

後に付ける派

if() { // 新しい行を使わない
	
}

elseの中括弧の位置も好みが分かれます。

中括弧の後に続ける派

if() {
	// 正常
} else if() {
	// 正常
} else {
	// 異常
}

中括弧の後に続けない派

if() {
	// 正常
}
else if() {
	// 正常
}
else {
	// 異常
}
最終更新:2014年01月15日 02:39