C言語 プログラミング

プログラミングの心構え十か条【C言語プログラミング講座(9)】

プログラミングで気を付けること十か条をまとまてみました。

プログラミングするときに気をつけていることです。

プログラミングの心構え十か条

C言語

C言語でプログラミングするときに常に心掛けているポイントが、下記の十項目になります。

プログラミング時の心構え十か条

(1)絶対落ちない、防衛的プログラミングを
(2)バグ発生時、まず自分から疑え
(3)一関数一機能で
(4)プログラミングは、デバッグ/テストを意識して
(5)アロケーションとフリー(初期化と終了処理)は同じ階層に
(6)オブジェクト指向で部品化を
(7)同一ロジックは、関数化、マクロ化、ループ・配列・構造体でまとめあげ
(8)バグの温床、初期化、ヌル文字、未アロケーション
(9)ヘッダファイル、ライブラリソースコードはお友達
(10)プログラミングにこだわりを

僕がプログラミングするときに、意識していることを上位10項目列挙すると、こういったところになります。
C言語でのプログラミングに特化するものもありますが、多くはプログラミングに共通の考え方に通じるものだと思います。

それぞれの内容について、以下にポイントをまとめてみます。
それぞれの心構えに注意しながら、実際に自分の手を動かしてプログラミングすることで、上達も早くなると考えています。。

(1)絶対落ちない、防衛的プログラミングを

他人がチェックしているとか、ここにはこの値が入ってくるとかの前提をたてたプログラミングをしないで、前提通りの値になっていることを自分のプログラムでチェックする習慣を持つということ。
これが、結局プログラムを早く・高品質で仕上げる結果になるなります。

例えば、関数の引数はきちんとチェックするように心がけています。
テストで確実に押さえきれるものであれば、アサーション関数(assert)も活用しています。


引数が1以上の整数を想定している。
int funcA(int i, int j)
{
	if (i < 0 || j < 0) {
		/* エラー処理 */
		return False;
	}
	
	return 0;
}

引数がNULLではないことを想定している場合には、前もってそれを仕込んでおく。
int funcA(char* pArg)
{
	assert(pArg != NULL); /* 引数はNULLではないことを想定 */
	
	return 0;
}

(2)バグ発生時、まず自分から疑え

そのバグを発生させる可能性が多少でも自分のプログラムにあるのなら、その個所はまずチェックします。
ライブラリやコンパイラ、他人のバグを疑うのは、一番最後です。

(3)一関数一機能で
関数化しないで、一関数が延々と続くコーディングは避けるべきです。
一関数は、1画面に収まるように(だいたい、25行程度)と教えられました。
再利用、デバッグ、変更、どれをとってもいいことがありません。

(4)プログラミングは、デバッグ/テストを意識して
容易にデバッグ、テストができるような仕掛け、トレース文等を最初から意識してプログラミングしておけば、テスト、デバッグで苦労しなくてすみます。

プログラミングの生産性は、バグに悩まされる時間をいかに削減できるかにかかっています。
ちょっとした心がけで、生産性は本当に数倍に上がります。

(5)アロケーションとフリー(初期化と終了処理)は同じ階層に
プログラミング時、階層(関数レベル)を合わせて、整然としたプログラミングを心がけよう、ということです。

関数の奥深くでアロケーションして、一番最後にフリーするとか、関数ネストの深いところで、いきなり終了したりとか、そんなプログラム書いていませんか?

この考え方は、ファイルのオープン、クローズや、業務の初期設定、終了処理等の実装でも同じです。

対になるものは、同じ階層であつかうこと、がプログラムをわかりやすくします。


int main()
{
	char* p;
	
	p = malloc(128);
	
	RunMyApp(p);
	
	free(p); /* RunMyAppの中でフリーはしない */
}

(6)オブジェクト指向で部品化を
何をするかを明確にして、そのオブジェクトとなるものを定義(C言語の場合は構造体定義)、それに対する一連の操作を関数化すれば、つかいまわしの可能な共通部品が出来あがります。
真のプログラマは、再利用するプログラマです。


typedef  struct MyStudent {
	int id;
	char name[128];
	int iage;
	int isex;
	int grade;
} MYSTUDENT;

int MyStudent_DataLoad(MYSTUDENT *pdata[]);
int MyStudent_Set(MYSTUDENT *pdata[]);

こんな形で例えば、自分の生徒を扱う関数群を定義すれば、部品として利用しやすくなります。
※ここまでするなら、C++を使ってクラスをつくればいい話ですが、組込み系等の一部処理系で、C++を使わない場合は、このようにすればオブジェクト指向プログラミングに近いことができます。
※オブジェクト指向は、あくまでも考え方なので、使い方によってはC言語でもオブジェクト指向の実装は可能になります。

(7)同一ロジックは、関数化、マクロ化、ループ・配列・構造体でまとめあげ
同じロジック、同一ロジックを何度も何度も書くから、プログラムが冗長になる。
コピーする前に、共通にならないか考えることが、結局プログラムを早く仕上げるコツである。

(8)バグの温床、初期化、ヌル文字、未アロケーション
C言語の場合のバグをつくりこみそうなポイントである。
初期化忘れ、文字列のヌル文字分の領域確保忘れ、未アロケーションの領域を使ってしまうこと。プログラミング時には、注意が必要。

(9)ヘッダファイル、ライブラリソースコードはお友達
プログラミング時の調査、使い方、動作がわからないときは、躊躇せずにヘッダファイルやライブラリのソースコードがあるならそれを見ると気づくことがあります。

プログラミングの技術向上にもつながると思います。

(10)プログラミングにこだわりを
プログラミングは、自分なりのこだわりを持つと上達します。

「より単純に、よりエレガントに、よりわかりやすく」

試行錯誤が、結局プログラミング技術の向上につながっていきます。

 

今回はここまでにします。

C言語の話は、この後も何回かに分けて投稿しますので、興味のある方は引き続きよろしくお願いします。

-C言語, プログラミング

Copyright© SIMPLEONESOFT (BLOG) , 2021 All Rights Reserved.