2012/06/18

C言語 マクロ #define

ソース中に何度も出てくる定数や小さな関数をマクロにすることで、開発効率及び処理速度を上げることが可能。マクロはコンパイルする直前に、プリプロセッサによってマクロ名を使った部分が置き換えられる。同じ処理が複数箇所に書かれる事になるので、定数や小さい処理に向いているが、型は指定できない。マクロのようなものはプリプロセッサ命令という。他に#includeなどがある。
書き方の注意点としては、マクロは1行で書く必要がありセミコロンなどは必要ない。2行に分けて書きたい場合は、\(バックスラッシュ)を使って折り返す。マクロ名と置き換え部の間にはスペースを入れる。マクロ名は区別しやすいように大文字を使うようにするなどルールを決めておいた方がよい。

マクロ

#include <stdio.h>
/* 関数形式マクロ定義 三項演算子*/
#define MIN(a,b) ((a)<(b) ? (a):(b))

int main(int argc, char **argv) {
   /* オブジェクト形式マクロ定義 */
   #define CALIBA 440
   int num1 = 380;
   int num2 = 350;
   /* マクロの使用 */
   printf("%dと%dでは%dが小さいです。",num1,num2,MIN(num1,num2));
   printf("基準音は%dHzです。\n",CALIBA);
   /* CALIBAマクロ無効化 */
   #undef CALIBA
   /* 下はコンパイルエラーになる */
   /*printf("基準音は%dHzです。\n",CALIBA);*/
   return 0;
}
マクロは関数の中でも定義できる。またundefで途中で無効化することこも可能。マクロの定義は三項演算子を使用している。式1 ? 式2 : 式3 の場合は式1が真なら式2となり、偽なら式3となる。
380と350では350が小さいです。
基準音は440Hzです。


マクロを使った定数の型はどうなる?

#include <stdio.h>
int main(void){
   #define DINT1 2147483647
   #define DINT2 2147483648U
   #define PI 3.14
   signed int a = 2147483647;
   unsigned int au = 2147483648U;
   double d = 3.14;
   float f = 3.14;
   printf("define     2147483647: %x\n",DINT1);
   printf("signed int 2147483647: %x\n",a);
   printf("define U     2147483648u: %u %x\n",DINT2,DINT2);
   printf("unsigned int 2147483648u: %u %x\n",au,au);
   printf("define 3.14: %x\n",PI);
   printf("float  3.14: %x\n",f);
   printf("double 3.14: %x\n",d);
   
   return 0;
}
マクロでは型の指定ができない。プリプロセッサで判断されるようだ。試しに16進数で表示することで、実際にどの型で処理されているか調べてみた。結果は以下の通りで、通常、整数ならsigned int扱いで、小数ならdouble扱いされるようだ。signed intを超える大きな桁を扱いたい場合は指定が必要なようだ。
define     2147483647: 7fffffff
signed int 2147483647: 7fffffff
define U     2147483648u: 2147483648 80000000
unsigned int 2147483648u: 2147483648 80000000
define 3.14: 51eb851f
float  3.14: 60000000
double 3.14: 51eb851f


C言語 ANSI C89 Meadow & MinGW GCC 目次はこちら