目次 このページのソースコードを表示
公開日:
更新日:

C言語には, マクロと呼ばれるものがあります. マクロとは, コンパイル前にある規則に従って文字を置き換える機能を持ちます[1].

ここでは, マクロの詳しい機能の説明を行います.

マクロの種類

マクロには, オブジェクト形式のマクロと関数形式のマクロの二種類があります[1][2].

オブジェクト形式

            #define 文字列1 文字列2

このように指定することで, 文字列1文字列2に置き換えられます.

以下がその例です.

            #define PortBaseType char
            
            #define IDLE_TASK_PRIORITY ((unsigned PortBaseType) 0U)
            
            #define LOW_PRIORITY (IDLE_TASK_PRIORITY)
            
            int main(){
                PortBaseType priority = LOW_PRIORITY;
                
                return 0;
            }

上は以下のように展開されます.

            
            int main(){
             char priority = (((unsigned char) 0U));
            
                    return 0;
            }
        

関数形式マクロ

            #define マクロ名(引数) 置き換えられる処理

このようにすることで, マクロ名置き換えられる処理に置き換わります.

以下がその例です.

            #define DeclareTaskLoop(name)  extern TaskHandle name;
        

ある場所でDeclareTaskLoop(TaskA)とすると, 次のように展開されます.

            extern TaskHandle TaskA;
        

複数行にわたる場合

マクロを定義するとき, 一行で収まらないときがあります. その場合, 改行したい場所でバックスラッシュ\を書くことで行替えが可能です.

以下がその例です.

        #define SuspendTask(name)                         \
            if((name) != NULL)                            \
            {                                             \
                TaskSuspend(name);                        \
            }

引数を文字列として置き換えたい

引数部はそのまま置き換えられます. 例えば次のようなことです.

        #define Macro(param) Func(param)
    

このマクロを定義し, Macro(ABCDE)とすると次のように展開されます.

        Func(ABCDE)
    

ここで, ABCDEを文字列として扱いたい場合があります. その場合, 処理部での引数の前に#を付けると, 文字列となります.

以下がその例です.

        #define Macro(param) Func(#param)

先ほどの例で, 次のように置き換わります.

        Func("ABCDE")

引数とマクロ内の文字を連結させたい

引数部とマクロ定義内の文字を連結させたい時があります. 例えば, 引数でタスク名(Blink)をもらい, 置き換え部でBlink_Taskとしたい時です.

その場合, 連結間に##を挟むことで連結できます.

以下がその例です.

        #define CreateTaskLoop(name, priority)                                                              \
                                                                                                            \
            TaskCreate(name##_Task, (signed PortChar*) #name, CONFIG_MINIMAL_STACK_SIZE, NULL, priority, &name);\

ある場所でCreateTask(TaskA)とすると次のように置き換わります.

        TaskCreate(TaskA_Task, (signed PortChar*) "TaskA", CONFIG_MINIMAL_STACK_SIZE, NULL, 0, &TaskA);
    

  1. ^ a b C言語のマクロの基本について(accessed: 2018/10/21)
  2. ^ 関数形式マクロ(accessed: 2018/10/21)
「https://contentsviewer.work/Master/Arduino/ArduinOS/define」から取得