#include / #define
| 対応: | C89(1989) |
|---|
プリプロセッサ命令はコンパイルの前処理段階で実行されます。『#include』でヘッダファイルを読み込み、『#define』で定数を定義します。いずれも行頭に『#』を付けて記述し、セミコロンは不要です。
構文
// 標準ライブラリのヘッダを読み込みます。 #include <ヘッダファイル名.h> // 独自のヘッダファイルを読み込みます。 #include "ヘッダファイル名.h" // 定数マクロを定義します(末尾にセミコロンは不要です)。 #define マクロ名 値 // 定数の定義例です。 #define PI 3.14159265358979 #define MAX 100 #define APP_NAME "MyApp"
主な標準ヘッダファイル一覧
| ヘッダ | 主な内容 |
|---|---|
| <stdio.h> | 標準入出力関数(printf、scanf、fopen など)を提供します。 |
| <stdlib.h> | メモリ管理(malloc、free)、乱数(rand)、変換(atoi)などを提供します。 |
| <string.h> | 文字列操作関数(strlen、strcpy、strcmp など)を提供します。 |
| <math.h> | 数学関数(sqrt、sin、cos、pow など)を提供します。 |
| <time.h> | 時刻・日付の取得・変換関数を提供します。 |
| <ctype.h> | 文字分類関数(isdigit、isalpha、toupper など)を提供します。 |
| <stdint.h> | 固定幅整数型(uint8_t、int32_t など)を提供します。 |
| <stdbool.h> | bool型・true・falseを提供します(C99以降)。 |
サンプルコード
sample_include_define.c
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
// 定数マクロを定義します。
#define PI 3.14159265358979
#define MAX_SIZE 10
#define APP_NAME "Circle Calculator"
// マクロは型がないことに注意します。
#define GRAVITY 9.8
int main(void) {
printf("== %s ==\n", APP_NAME);
// 定数として使用します。
double radius = 5.0;
double area = PI * radius * radius;
double circ = 2.0 * PI * radius;
printf("半径 %.1f の円\n", radius);
printf("面積: %.4f\n", area); // 『78.5398』と出力されます。
printf("円周: %.4f\n", circ); // 『31.4159』と出力されます。
// MAX_SIZE を使って配列サイズを定義します。
int arr[MAX_SIZE];
for (int i = 0; i < MAX_SIZE; i++) {
arr[i] = i * i;
}
printf("arr[5] = %d\n", arr[5]); // 『25』と出力されます。
// math.h の sqrt を使います(リンク時に -lm が必要な場合があります)。
printf("√2 = %.6f\n", sqrt(2.0)); // 『1.414214』と出力されます。
// GRAVITY を使った落下距離の計算です。
double t = 2.0; // 秒
double distance = 0.5 * GRAVITY * t * t;
printf("%.1f秒後の落下距離: %.1fm\n", t, distance); // 『19.6m』と出力されます。
return 0;
}
コンパイルして実行すると次のようになります。
gcc include_define.c -o include_define -lm ./include_define == Circle Calculator == 半径 5.0 の円 面積: 78.5398 円周: 31.4159 arr[5] = 25 √2 = 1.414214 2.0秒後の落下距離: 19.6m
const と enum による型安全な定数定義
『#define』の定数マクロはプリプロセッサによる単純なテキスト置換で、型情報がありません。C言語では型チェックが欲しい場合に『const』変数や『enum』を使う方法もあります。
define_vs_const.c
#include <stdio.h>
/* #define: 型なし、デバッガに名前が出ない場合がある */
#define SPEED_OF_LIGHT 299792458
/* const: 型あり、デバッガでも名前が見える */
const double GRAVITY = 9.80665;
/* enum: 関連する整数定数をまとめる */
enum Direction { NORTH = 0, EAST, SOUTH, WEST };
int main(void) {
printf("光速: %d m/s\n", SPEED_OF_LIGHT);
printf("重力加速度: %.5f m/s^2\n", GRAVITY);
enum Direction dir = EAST;
printf("方向: %d\n", dir); /* 『方向: 1』と出力されます。 */
return 0;
}
コンパイルして実行すると次のようになります。
gcc define_vs_const.c -o define_vs_const ./define_vs_const 光速: 299792458 m/s 重力加速度: 9.80665 m/s^2 方向: 1
よくあるミス
よくあるミス: #define にセミコロンを付ける
『#define』の末尾にセミコロンを付けると、マクロが展開されたときにセミコロンが余分に挿入され、コンパイルエラーや意図しない動作の原因になります。
define_semicolon_ng.c
#include <stdio.h>
/* NG: セミコロンを付けるとテキスト置換で「100;」になる */
#define MAX_NG 100;
int main(void) {
int arr[MAX_NG]; /* arr[100;] に展開されてコンパイルエラー */
(void)arr;
return 0;
}
修正後は次の通りです。
gcc define_semicolon_ng.c -o define_semicolon_ng define_semicolon_ng.c: error: expected ']' before ';' token
define_semicolon_ok.c
#include <stdio.h>
/* OK: セミコロンを付けない */
#define MAX_OK 100
int main(void) {
int arr[MAX_OK];
for (int i = 0; i < MAX_OK; i++) arr[i] = i;
printf("arr[99] = %d\n", arr[99]); /* 『arr[99] = 99』と出力されます。 */
return 0;
}
修正後は次の通りです。
gcc define_semicolon_ok.c -o define_semicolon_ok ./define_semicolon_ok arr[99] = 99
概要
『#include <...>』はコンパイラの標準インクルードパスを検索し、『#include "..."』は現在のファイルのディレクトリを最初に検索します。自作ヘッダには二重引用符を使うのが一般的です。
『#define』で定義した定数マクロはプリプロセッサが単純なテキスト置換を行います。マクロには型がないためコンパイラの型チェックが受けられません。定数にはできるだけ『const』変数や『enum』を使い、型安全なコードを書くことを推奨します。
関数マクロ(引数を取るマクロ)については『#define(関数マクロ)』を、条件付きコンパイルについては『#ifdef / #ifndef』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。