メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.479) 木構造マクロ  2004/07/26


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第479回 木構造マクロ
 発行    2004年7月26日(月曜日)
 発行数   約2800

{magclick}
/*========================================================*/
 はじめに ( 決り文句 )
/*========================================================*/
・このメールマガジンは、主にまぐまぐさんから発行しています。
・ジャンルは、マルチメディアのプログラム、C言語です。
・横60文字で作成し、インデントは大抵半角スペース4つです。
・ここで扱うプログラムは、C言語と半光年以内のものです。
・登録解除は、メルマガのホームページでお願いします。
・過去ログはバックナンバー(下欄参照)を活用して下さい。
・内容は私が感じたもので、最新の技術も、へたれもあります。
・わかりやすさを優先させる為、たまに嘘があるかもしれません。
・セキュリティ突破のため、暗号化された単語があります。

/*========================================================*/
 ご挨拶
/*========================================================*/

 こんにちは。あゆしゃです。

 先日、私としては非常に珍しいことに、

★お庭の草刈をしました。

 いやぁ、

★1メートルほど伸びていたので(笑)

 電気草刈機があるのですが、

★コードを伐採してしまうので(笑)<2度も経験

 鎌で草刈しました。

★火炎斬! とばかりに(笑)

 熱かったですが、楽しかったです。するとどうでしょう?

★信じられない大雨が。

 ただの夕立かと思っていたら、

★★★ 大雨による死者が出ました。 ★★★

 車を拭くと雪が降るし・・・雨あゆしゃですか?

{magclick}
/*========================================================*/
 今回のお題  << 木構造マクロ >>
/*========================================================*/

 以前、木構造をクラスで実装しようとして、大失敗しました。

 今回はその反省を持って、木構造処理はべたな関数にします。

 変数1つにつき、専用の関数をそれぞれに用意しましょう。

 そうすると、呼び出し元もすっきりします。

★そんな数の関数を書いていられません。

 そこで最終兵器、マクロの登場です。


struct tree_t
{
    tree_t* left;
    tree_t* right;
    char key[ 1 ];
} *tree = NULL;

 これを、

struct tree_t
{
    DEF_TREE_ITEM( tree_t );
} *tree = NULL;

 という感じで宣言できるようにしましょう。つまり、

#define DEF_TREE_ITEM( type ) \
    type* left; \
    type* right; \
    char key[ 1 ];

 というマクロを作ってしまえばいいのです。

 (マクロ定義を別ファイルにすると)メンバがインテリに表示
されなくなってしまいますが、まぁ、いいでしょう。

 メモリの取得処理をはじめとする関数群も、

DEF_TREE_FUNC( tree_t, string, tree );

 という記述だけでできるようにしましょう。つまり、

#define DEF_TREE_FUNC( type, name, var ) \
\
type* new_##name( char* key, int len )\
{\
    type* pt = ( type* )calloc(\
        1, sizeof( type ) + len );\
    if( pt ) {\
        memcpy( pt->key, key, len );\
    }\
    return pt;\
}\
\
type* find_##name( char* key, int len )\
{\
    type* pt = tree;\
    while( pt ) {\
        int c = strncmp( pt->key, key, len );\
        if( ! c ) c = pt->key[ len ];\
        if( ! c ) break;\
        if( c > 0 ) pt = pt->left;\
        else pt = pt->right;\
    }\
    return pt;\
}\
\
type* add_##name( char* key, int len )\
{\
    type** ppt = &var;\
    while( *ppt ) {\
        type* pt = *ppt;\
        int c = strncmp( pt->key, key, len );\
        if( ! c ) c = pt->key[ len ];\
        if( ! c ) break;\
        if( c > 0 ) ppt = &pt->left;\
        else ppt = &pt->right;\
    }\
    if( ! *ppt ) *ppt = new_tree( key, len );\
    return *ppt;\
}

 ちょっと長いですが、それだけ省略できるものが大きいという
ことです。

 コメントを入れたければ、/*〜*/ を¥の「左」に入れることが
できます。右はだめですよ?

 これさえあれば、


struct tree_t
{
    DEF_TREE_ITEM( tree_t );
} *tree = NULL;
DEF_TREE_FUNC( tree_t, string, tree );

 たったこれだけで、木構造付データが使用可能になります。

 しかも、構造体の中には好きなメンバを追加し放題です。

 さらに、マクロを使う利点として、

★木構造を含む木構造という複雑な定義を簡単に実現可能

 これはうれしいです。たとえば、

struct shop_t
{
    struct item_t
    {
        DEF_TREE_ITEM( item_t );
    } *item;
    DEF_TREE_FUNC( item_t, item, item );
} *shop = NULL;
DEF_TREE_FUNC( shop_t, shop, shop );

 不特定多数のお店の情報があり、

 お店ごとに不特定多数のアイテムごとの情報(売上高など)を
持っている、という感じの複雑な情報も、

 はい、クリア〜^^ って感じです。

{magclick}
/*========================================================*/
 さいごに
/*========================================================*/

 ## は、変数名称を魔導合成する演算子です。

 あと、メモリの開放処理も必要ですよ?

{magclick}
/*========================================================*/
 次回予告
/*========================================================*/

 次回は7月28日(水曜日)に、第480回をお送りします。
 お題は「マクロ応用など」

 木構造をネストすると、デストラクタとしての処理が必要に
なります。

 マクロの引き数として Cコードを追加するのは簡単ですが、
終了処理がない場合、引き数を省略するには?

 カンマ付の Cコードを引き数としてマクロに渡すには?

 お楽しみに!

/*========================================================*/
 最後の決り文句
/*========================================================*/
 このメールマガジンは、まぐまぐさんから発行しています。
 このメールマガジンを解除したい場合は、まぐまぐさんをご利用
ください。このメルマガのまぐまぐアイディーは最後にあります。
 このメールマガジンには広告が挿入されていますか?
 このメールマガジンの内容に文面の引用はありませんか?
 めーらっくすの場合はめーらっくすの利用方に従ってください。
 このメールマガジンの内容の、転用、流用、宣伝、リンク、
Ctrl+Up、Downとか なんて大歓迎です。

{magclick}
/*========================================================*/
 
/*========================================================*/

発行者 あゆしゃ

ホームページ::あゆしゃの世界
http://ayusya.hp.infoseek.co.jp/

ご意見・ご感想・ご質問メール
mailto:ayusya@flamenco.plala.or.jp

まぐまぐ::アイディー
0000020674

まぐまぐ::登録と解除
http://www.mag2.com/m/0000020674.htm

まぐまぐ::バックナンバー
http://jazz.tegami.com/backnumber/frame.cgi?id=0000020674

めーらっくす::アイディー
MM3E1AEE285AB4F

めーらっくす::登録と解除
http://www.mailux.com/mm_dsp.php?mm_id=MM3E1AEE285AB4F 

めーらっくす::バックナンバー★最近のものならこちらが便利★
http://www.mailux.com/mm_bno_list.php?mm_id=MM3E1AEE285AB4F

ブラウザの閉じるボタンで閉じてください。