0
1

More than 3 years have passed since last update.

[C言語]defineテーブル~複数の宣言、処理の一元管理~

Last updated at Posted at 2020-10-25

[C言語]defineテーブル~複数の宣言、処理の一元管理~

概要

C言語のdefine定義を利用して複数の宣言、処理を一ヶ所で管理する方法です。

構成

defineテーブルの宣言は、展開用define関数を複数定義する形で行います。複数行に定義する場合は行末に「\」が必要です。
defineテーブルの展開は、展開用define関数を宣言してからdefineテーブルを展開します。
1ファイル中で複数回展開することを考慮すると展開後にundefで展開用define関数を削除しておいた方が良いでしょう。
以下、enumの宣言と対応する名称文字列をdefineテーブルを利用して宣言するサンプルです。

    //define tableを宣言する
    //名称(table,item)は任意の名称で構いません。
    //itemはdefine関数の呼び出しであり、展開したい内容を引数とします。
    #define table   \
        item(a)     \
        item(b)     \
        item(c)     \

    //-------------------------
    //enumに展開する
    #define item(prm)   prm,    
    enum{
        table
    };
    #undef item

    //-------------------------
    //enumの名称文字列に展開する
    #define item(prm)   #prm ,  
    char*enum_name[]={
        table
    };
    #undef item

    #include<stdio.h>
    void main()
    {
        printf("ENUM(%d):%s\n",a,enum_name[a]);
        printf("ENUM(%d):%s\n",b,enum_name[b]);
        printf("ENUM(%d):%s\n",c,enum_name[c]);
    }

tableの宣言のみでenumとその名称enum_nameの定義が行われています。
defineテーブルは関数内の処理にも展開可能なので、main関数は以下のように書き換えることもできます。

    #define item(prm)   printf("ENUM(%d):%s\n",prm,enum_name[prm]);
    void main()
    {
        table
    }
    #undef item

enum毎に名称を変更したい場合は以下のように展開用define関数の引数を増やし、展開時の宣言で利用する引数を変更することで個別の名称を利用することもできます。

    #define table   \
        item(a,"A")     \

終わりに

C言語は定義間の関連付けをほぼ人力に頼っています。
しかし、定義を変更した際に関連する他の定義や処理を修正しなければいけないケースは多く、冗長な作業になることが多いと感じます。
このdefineテーブルを利用すると、一ヶ所で宣言の関連付けを行えるので、整合性の確保や修正作業の手間の削減に効果があると思います。
C言語でO/Rマッピングの様な事(構造体とSQL文の関連付け)をやりたい場合や、メンバ数の多い構造体でメンバ毎に処理が必要な場合などにも利用できます。

※注意点

defineテーブルのコーディング方法はあまり一般的ではありません(というか人が使っているところを見たことがありません)。
会社や学校で利用する際には、利用して問題ないか確認を取ってからにしてください。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1