【C言語入門】define(マクロ)の使い方(関数や条件付きマクロも解説)

define(マクロ処理)の 基本から応用まで

あなたはdefineを使ってますか? defineはC言語で自ら定義した文字列を定数や式で置き換える場合に使用します。

この置き換える処理のことをマクロ処理といいます。定数や式を自ら定義しその定義をコードの中でたくさん使う場合には、defineを使ってマクロ処理をしておくと便利です。のちのちに定義を変更したい場合が発生しても、defineを使って定義した箇所を変更するだけで済みます。

この記事ではdefine(マクロ処理)についての基本的なことから、文字列を値や式に置換したり、if definedで条件付きマクロを使うなど応用的な使い方の内容についても解説していきます。

目次

define(マクロ)とは

defineとはプリプロセッサへの指示内容のひとつです。ブリプロセッサとは、コンパイル前に処理を行うプログラムのことです。

コンパイル時の前処理として、マクロ名で指定した文字列を定数や式で置き換えます。この置き換えのことをマクロ置換といいます。

またこの処理のことをマクロ処理といいます。マクロ処理を定義するためにdefineを使用します。

defineで文字列を値に置換

defineは下記のように記述して使用します。

#define マクロ名 定数や式

定数について

マクロ名で指定した文字列を定数で置換する方法について説明します。定数には数値や文字列を記述することができます。

定数に置換するマクロ名は一般に全て大文字で記述します。数値を定義したマクロは計算式中で使用することもできます。

文字列を定義したマクロはchar型のポインタへ代入することもできます。それではサンプルコードで確認していきましょう。

#include <stdio.h>
 
#define PI 3.14f // float型定数
#define CIRCLE_RATIO "円周率" // 文字列定数
 
int main(void) {
    double area = PI * 10 * 10; // 定数を使った計算
    char *ptr = CIRCLE_RATIO; // ポインタ型への代入
    
    printf("%sは: %f\n", ptr, PI);
    printf("半径10の円の面積は: %f\n", area);
    
    return 0;
}

実行結果:

円周率は: 3.140000
半径10の円の面積は: 314.000000

このサンプルコードでは、defineを使って数値の定数「PI」と文字列の定数「CIRCLE_RATIO」を定義しています。

数値の定数「PI」を使って計算を行っています。また、文字列の定数「CIRCLE_RATIO」をchar型のポインタ「ptr」に代入しています。

defineで文字列を式に置換

マクロ名で指定した文字列を関数で置換する方法について説明します。

関数の定義について

defineを使って関数を定義することができます。「#define」句の記述の後に関数名と引数を記述し、その後に処理内容を記述します。

#define 関数名(変数) (処理内容)

関数形式マクロでは引数は型を指定する必要はありません。また戻り値を「return」句で返す必要もありません。

それではサンプルコードで確認していきましょう。

#include <stdio.h>
 
#define PI 3.14
#define area(r) (PI*r*r)
#define prt(f) printf("%f\n", f)
 
int main(void) {
    prt(area(10.0f));
 
    return 0;
}

実行結果:

314.000000

このサンプルコードでは2つの関数をdefineマクロで定義しています。処理内容は「( )」カッコで囲っておいた方が意図しない処理が起こらず安心です。

なお関数の作り方については、こちらのサイトで詳しく説明していますので、こちらを参考にしてください。

複数文からなるマクロ

defineを使って関数を定義する方法について、これまでは1行で定義できるものについて説明しています。複数行の文からなる関数の定義については、do-while文を使用します。

記述方法は下記のとおりになります。

#define 関数名(引数) do {処理1; 処理2; ・・・; } while(0)

whileの条件はfalse(ゼロ)ですので、do-whileのループは一度だけ実行されます。

それではサンプルコードで確認していきましょう。

#include <stdio.h>
 
#define PI 3.14f // float型定数
#define calc(r) do {double area = PI * r * r; printf("半径%fの円の面積は: %f\n", r, area); } while(0)
 
int main(void) {
    calc(10.0f);
    
    return 0;
}

実行結果:

半径10.000000の円の面積は: 314.00000

このサンプルコードでは、defineを使ってcalc関数を定義しています。

calc関数では2つの処理を記述しているのでdo-while文で囲っています。定義したcalc関数をmain関数内で使用しています。

if definedで条件付きマクロ

前述のdefineで定義したcalc関数のサンプルコードではマクロで別に定義した定数「PI」を使用しています。しかし、定数「PI」が定義された定数であるかどうかを判断してからマクロ関数内で使用する方が望ましいです。

このような場合にif definedを使用します。if definedは下記のように記述します。

#if defined(マクロ定義)
    #define マクロ定義を使った式
#endif

それでは、サンプルコードで確認していきましょう。

#include <stdio.h>
 
#define PI 3.14f // float型定数
#if defined(PI)
    #define calc(r) do {double area = PI * r * r; printf("半径%fの円の面積は: %f\n", r, area); } while(0)
#endif
 
int main(void) {
    calc(10.0f);
    
    return 0;
}

実行結果:

半径10.000000の円の面積は: 314.000000

このサンプルコードでは、if definedを使って定数「PI」が定義された定数かどうか判断しています。判断が正しい場合に定数「PI」を使った処理を行うcalc関数を定義しています。

まとめ

ここでは、defineの使い方について説明しました。定数や式を自ら定義しその定義をコードの中でたくさん使う場合には、defineを使ってマクロ処理をしておくことをオススメします。

のちのちその定義を変更したいときにdefineで定義した箇所だけ変更すれば済むので便利です。使いこなすことができるように、この記事を何度も参考にして下さいね!

この記事を書いた人

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
info@sss-lab.com

目次