『Cプログラミング診断室』目次次(第5章 管理は複雑に 修正例)

第5章 管理は複雑に

ほとんど同じ


■ほとんど同じ■

それぞれ、「対」になるファイルの相違点は何でしょうか?一方にはexternがあり、他方にはな いだけでしょう。これならば、一方のファイルをコピーし、externの部分だけを書き換えれば、他 方のファイルができてしまうでしょう。きわめて機械的な単純な変更作業ではないですか。

我々は、機械的な作業だけが何よりも得意なコンピュータのプログラムを組んでいるのですから、 このような作業は、当然コンピュータにやらせるべきです。では、どうすれば良いでしょうか。

まず考えられるのが、externのついているファイルから、externを取り除いてしまうツールを作 ることでしょうか。これでも、ちょっと問題になるのは、グローバル変数に初期値が代入されてい る個所があることです。この部分は、逆になるので、一方から他方を単純には作れません。

では、両方を含むファイルを作り、ツールで、内部で宣言するファイルと、extern宣言するファ イルを作るとよいですね。代入部分は、extern宣言する方のファイルに対しては削除します。これ で、めでたく解決ですかね。では、そのツールの仕様と作成は読者にまかせましょうか。

■マクロで対処■

さて、ツールはできましたか。でも、本当はツールなど作る必要もないのです。ほとんど似てい るものを作る時こそ、「マクロの出番」なのです。もしツールを作っていたら「バカ」です。

externになったり、ブランクになったりするのは、グローバル変数を、そこで確保したいか、他 で確保(extern)させたいかなので、その判定をする基準となるものが必要になります。そのために、 ここでは、GLOBAL_VALUE_DEFINE というマクロ名をフラグとして使うことにしましょう。このマク ロ名が#defineで定義されているときは、ここで変数を宣言し、未定義のときはextern宣言します。 このためには、

	#ifdef	GLOBAL_VALUE_DEFINE
	#define	GLOBAL
	#else
	#define	GLOBAL	extern
	#endif
のように、#ifdefでGLOBALというマクロ名を空白かexternに置換します。これで、
	GLOBAL	short	SV_HEAD;
と書かれていた個所のGLOBALの部分は、希望通りに置換されます。GLOBAL_VALUE_DEFINE はどこか のファイルで定義してしまえば、これで終りです。今回の例では、table.c の先頭に入れておくの が適当なようです。つまり、mktable.c の先頭を、
	#define  GLOBAL_VALUE_DEFINE	
	#include "defglobal.h"
	#include "dbstruct.h"
	#include "data.h"
のように書くことで、全てのグローバル変数の実体をメモリ上に確保し、他のファイルからは全部 外部参照すると美しいですね。

■初期値設定■

グローバル変数にも、初期値設定が必要なことがあります。今回の例では、
    int   chrx_d  = 8;
    int   chry_d  = 16;
    int   crtbias = 0;
のような初期値があります。' = 8 ' の部分もGLOBAL_VALUE_DEFINEによって、無くしたり、その まま残したりしなければいけません。

これもマクロで対応できます。

    #define	GLOBAL_VAL(v)  = (v)
というマクロがあると、
    GLOBAL  int	  chrx_d   GLOBAL_VAL(8);
    GLOBAL  int	  chry_d   GLOBAL_VAL(16);
    GLOBAL  int   crtbias  GLOBAL_VAL(0);
は、元のように展開されますね。代入部分を無くすには、
    #define	GLOBAL_VAL(v)  /* */
としておきます。/* */ の部分は、もちろん無くても構いません。「無くなるよ」ということを強 調しているだけです。したがって、前のと一緒にすると、
    #ifdef    GLOBAL_VALUE_DEFINE
    #define   GLOBAL
    #define   GLOBAL_VAL(v)  = (v)
    #else
    #define   GLOBAL	extern
    #define   GLOBAL_VAL(v)  /* */
    #endif
と書けばいいですね。

Cプリプロセッサのマクロ展開(置換)は、単なる文字列の置き換えをしているだけですから、 このようなことが簡単にできます。

美しいパズルとは

ナンプレ問題
自動生成


これで、今日から
貴方もパズル作家

Cパズル
プログラミング
〜再帰編〜



Copyright1996 Hirofumi Fujiwara. No reproduction or republication without written permission
『Cプログラミング診断室』目次次(第5章 管理は複雑に 修正例)