【C】初めてのC言語（23. 条件付きコンパイル）

# はじめに

* これまでの学習に続いて、今回はdefineとifdef～endifを用いた条件付きコンパイルについて学んだ結果をまとめてみました。


# 学習環境

* 今回は[paiza.io](https://paiza.io/ja/projects/new)のC言語のエディタを使いました。

# defineによるマクロ処理（復習）

https://qiita.com/nkojima/items/b89cb01c759ecdb7165c

## マクロ処理の概要

* defineによるマクロ処理は、「ソースコード内のある文字列を別の文字列に置換する」という機能を持っています。
  * この置換処理のことを「展開」と呼ぶそうです。 
* 以下のコードでは、プリプロセッサによって「PIが3.1415に置き換えられる」という処理が行われます。

```c:Main.c
#include <stdio.h>

#define PI 3.1415

int main(void){
    int r = 2;
    printf("半径%dの円の面積：%f\n", r, r * r * PI);
    return 0;
}
```

```text:実行結果
半径2の円の面積：12.566000
```

## マクロ処理の副作用

1. 型や構文のチェックが効かない。
2. 危険な定数展開をしてしまうリスクがある。
   * 予約語の「int」を別のものに置換してしまうなどのリスクがあります。

# ソースコード分岐処理とdefine

* ここまでdefineによるマクロ処理を見ると良いことが無いように思えますが...
* ifdef～endifによるソースコード分岐処理と組み合わせて使うと「条件に合致する時にのみコンパイル対象となるコードを記述する」ということが可能になります。
   * そういえばifdef～を使って、Windows用とLinux用の処理を分岐させているコードを見たような気が...

```c:Main.c
#include <stdio.h>

#define DEBUG_MODE 5

int main(void){

int x = 0;

// DEBUG_MODEが宣言されている時に有効
#ifdef DEBUG_MODE
    printf("デバッグモードです。\n");
#endif

// DEBUG_MODEが宣言されていない時に有効
#ifndef DEBUG_MODE
    printf("リリースモードです。\n");
#endif


#if (DEBUG_MODE==1)
    x=1;
#elif (DEBUG_MODE==2)
    x=2;
#elif (DEBUG_MODE==3)
    x=3;
#else
    x=9;
#endif

    printf("%d\n", x);
    return 0;
}
```

```text:実行結果
デバッグモードです。
9
```



# 補足：これまでの学習の歩み

* [【C】初めてのC言語（1. Hello world）](https://qiita.com/nkojima/items/518c1a4ec06861d74b3c)
* [【C】初めてのC言語（2. 四則演算とフォーマット指定子）](https://qiita.com/nkojima/items/36ea93b7296ce9e8a55b)
* [【C】初めてのC言語（3. ポインタ）](https://qiita.com/nkojima/items/825bb9f931016faccd68)
* [【C】初めてのC言語（4. 構造体）](https://qiita.com/nkojima/items/40a1101f2f6f5800bc2d)
* [【C】初めてのC言語（5. 関数）](https://qiita.com/nkojima/items/1fa3317c04f25fe24276)
* [【C】初めてのC言語（6. 配列）](https://qiita.com/nkojima/items/eda3ff6675b47e7ab5f0)
* [【C】初めてのC言語（7. for文）](https://qiita.com/nkojima/items/a5659098f7e5275a96ec)
* [【C】初めてのC言語（8. 2次元配列）](https://qiita.com/nkojima/items/f5eb25a4f8d1725faa89)
* [【C】初めてのC言語（9. 関数のプロトタイプ宣言）](https://qiita.com/nkojima/items/57318d74bdfa670bf72e)
* [【C】初めてのC言語（10. 構造体配列）](https://qiita.com/nkojima/items/75530a3ca63924a14397)
* [【C】初めてのC言語（11. ヘッダファイル）](https://qiita.com/nkojima/items/a10cd943ed66e0cea7fd)
* [【C】初めてのC言語（12. 3つのからくり構文＋ポインタ演算）](https://qiita.com/nkojima/items/83cb40ec01cd6a6e6a87)
* [【C】初めてのC言語（13. メモリを扱う標準関数）](https://qiita.com/nkojima/items/13c8d942f282beb3c212)
* [【C】初めてのC言語（14. ヒープの利用）](https://qiita.com/nkojima/items/837557cc86ce9697611a)
* [【C】初めてのC言語（15. sizeofの注意点）](https://qiita.com/nkojima/items/6c9a3ba04c6348219578)
* [【C】初めてのC言語（16. 文字列の基本）](https://qiita.com/nkojima/items/d87ce0cb15dd1a26f21a)
* [【C】初めてのC言語（17. 文字列リテラル）](https://qiita.com/nkojima/items/527ef37d84cf9b201dc5)
* [【C】初めてのC言語（18. 文字列の受け渡し）](https://qiita.com/nkojima/items/a07ac9a9bb3b41296f1e)
* [【C】初めてのC言語（19. 文字列とバッファオーバーフロー）](https://qiita.com/nkojima/items/4d9cec9e686aee41eec2)
* [【C】初めてのC言語（20. 文字列を扱う標準関数）](https://qiita.com/nkojima/items/12ac7b9b64baae1a67d1)
* [【C】初めてのC言語（21. コマンドライン引数と二重ポインタ）](https://qiita.com/nkojima/items/818b857c81fccdfe65c2)
* [【C】初めてのC言語（22. マクロ処理）](https://qiita.com/nkojima/items/b89cb01c759ecdb7165c)

# 参考URL

* [スッキリわかるC言語入門 第2版](https://www.amazon.co.jp/dp/4295012785/)
  * p.505～p.507