「ソフテックだより」では、ソフトウェア開発に関する情報や開発現場における社員の取り組みなどを定期的にお知らせしています。
さまざまなテーマを取り上げていますので、他のソフテックだよりも、ぜひご覧下さい。
ソフテックだより(発行日順)のページへ
ソフテックだより 技術レポート(技術分野別)のページへ
ソフテックだより 現場の声(シーン別)のページへ
ソフトウェア開発の性質上、一度開発したシステムは、何度も機能アップが繰り返される傾向が強く、高い保守性が必要となります。とりわけ、複数人が関わるような大規模な開発では、各個人がバラバラにプログラミングしていたのでは、ソースコードの均質化が図れずに結果として保守性を保つことは容易ではありません。
高い保守性を保つためには
ソースコードであることが非常に重要と考えます。読み難く、統一されていないコードでは、プログラムの解析ミスが起こりやすく、バグを発生させてしまう恐れがあり、非常に危険です。
そのため、安全性を高めるためにもプロジェクト毎にコーディング規約を規定し、統一されていることが必要となってきます。
今回は、ある組み込みソフトウェア開発で使用したコーディング規約の一例を紹介したいと思います。
システムの保守性を高めるためには、実装工程(開発工程)で保守性の高いコードを作成する必要があります。
保守性の高いコードとは?
こうした条件を満たすコードを作成するためには、なんらかの「品質基準」に従ってプログラミングする必要があります。このソースコードの品質基準が「コーディング規約」です。
ファイルや関数に何も説明がないと、どのような目的で、どのような処理をしているのか、一目ではわかりません。
下記例のようなヘッダ(説明)を付けることで、ここでどのような処理をしているのかをイメージしやすく、可読性を高めることが期待できます。
//-------------------------------------------------------------------------------- // ファイル名 : APPMT.C // 概要 : Application (Multi Task) startup // 詳細 : アプリケーション (マルチタスク) スタートアップ // main task を起動する // 履歴 : 2006/06/07 UserName 新規作成 //--------------------------------------------------------------------------------
//---------------------------------------------------------------------------- // 関数名 :main // 概要 : // 戻り値 :なし // 引数 :int argc // 説明 // 引数 :char *argv[] // 説明 // 引数 :char *envp[] // 説明 // 作成 :2006/06/07 UserName //---------------------------------------------------------------------------- void main(int argc, char *argv[], char *envp[])
メンテナンスの必要に駆られて解析をおこなう場合、ソースコードを解析するのにキーワード検索は有効です。しかし、コメントのスタイルがバラバラだと、検索キーワードを複数回指定しなければならない場合があり、非常に面倒です。また、検索漏れが起こる場合も考えられ、保守性を下げる要因となりえます。
そのため、下記のように、スタイルを決めておくと良いと思います。
コードには判断文(if,for,while,case)が多く含まれています。
この判断文にコメントをつけるだけで処理内容が一目でわかるようになります。
ソースコードの可読性を向上させるのは、コードのスタイルを統一することだけではありません。コードの中に的確でかつ、わかりやすいコメントを記述することも可読性の向上に大きくつながります。
変数名のみでもある程度の情報を得やすくするために一般的なネーミング規約の一つであるハンガリアン記法と記憶子を組み合わせて変数名を命名します。
ハンガリアン記法とは、変数の名前に型などの情報を縮めて付加する方法のことです。
プレフィックス1 | データ型 |
---|---|
c | char |
by | BYTE(unsigned char) |
u | UINT(unsigned int) |
n | int |
b | BOOL(int) |
w | WORD(unsigned short) |
l | long |
dw | DWORD(unsigned long) |
s | 文字列 |
sz | ASCIIZ文字列 |
p | ポインタ |
lp | long(far)ポインタ |
np | nearポインタ |
プレフィックス2 | 記憶子 |
---|---|
g | extern |
s | static |
c | const |
なし | ローカル |
インデントがバラバラだと、読み難いコードになってしまいます。
読み難いコードはバグの元です。
そのため、インデントはハードタブで4文字と規定しています。
if文やfor文でネストが深くなると、処理が複雑で、解読が非常に困難になってしまいます。そのため、ネストレベルを5階層までと規定しています。
例) if(a == 0) //ネストなし { if(b == 1) //ネスト1 { if(c == 2) //ネスト2 { if(d == 3) //ネスト3 { if(e == 4) //ネスト4 { a = 1; //ネスト5 } } } } }
とは言っても、処理が複雑になったり、判断条件が増えると、ネストレベルは深くなってしまいます。その対策として、次の方法が考えられます。
判定文の後に処理をする必要が無い場合には、returnで返すことにより、ネストが深くなることを防ぐことが出来ます。
例)
if(a != 0)
{
return;
}
一定のまとまりのある処理を関数化して、その関数を呼ぶことでも、ネストが深くなることを防ぐことが出来ます。
定数に小文字を使うと、変数なのか、定数なのか、見ただけではわかりません。一目で定数とわかるように、定数の場合は小文字を禁止し、大文字を使うように規定しています。
例) #define MAX_COUNTER 10 →OK #define Max_Counter 10 →NG(小文字は使用禁止)
いかがでしたか?
自分の開発したシステムであっても、長時間経過すると、どのような処理をしているのか、忘れてしまいがちです。「3日前に書いたコードは他人のコードと同じ」ということも言われています。このような場合、わかり易く、読みやすいコードは、確実に効率よく、正確に解析をすることが出来ます。
ほんの一例を紹介させていただきましたが、C言語でソフトの作成を始める方にも参考にしていただければ幸いです。
(T.M.)
関連ページへのリンク
関連するソフテックだより