■ プリプロセッサ
define - プリプロセッサマクロ定義
~~~c
include <stdio.h>
define COUNT 0x5
define MULTIPLE_COUNT (2 * COUNT)
define DEVIDE_COUNT(x, y) *1
int main() { printf("%d\n", COUNT); printf("%d\n", MULTIPLE_COUNT); printf("%d\n", DEVIDE_COUNT(9, 2)); } ~~~
c:実行結果
5
10
4
既定義マクロ
~~~c
include <stdio.h>
int main() { printf("LINE : %d\n", LINE); printf("FILE : %s\n", FILE); printf("DATE : %s\n", DATE); printf("TIME : %s\n", TIME); } ~~~
c:実行結果
LINE : 5
FILE : test.c
DATE : Dec 1 2017
TIME : 00:00:00
undef - マクロ定義削除
~~~c
define COUNT 0x5
undef COUNT
~~~
# - 文字列化演算子
マクロ引数をダブルクォーテーションを付けた文字列に変換する
~~~c
include <stdio.h>
define COUNTB 0x6
define STRINGIFY1(x) #x
define STRINGIFY2(x) STRINGIFY1(x)
int main() { // 一段階のマクロでは引数xはマクロ展開されない printf(STRINGIFY1(COUNTB));
// 引数xのマクロ展開を先に実施するために二段階のマクロを使用
printf(STRINGIFY2(COUNTB));
} ~~~
c:実行結果
COUNTB
0x06
## - 文字列連結演算子
~~~c
include <stdio.h>
define COUNTB 0x6
define COMBINE_COUNT(x, y) x ## y
int main() { printf("%d\n", COMBINE_COUNT(COUNT, B)); } ~~~
c:実行結果
6
include - ファイルインクルード
~~~c // 標準ヘッダファイルのインクルード // 標準ヘッダファイル格納ディレクトリのみ探索
include <stdio.h>
// 作成ヘッダファイルのインクルード // カレントディレクトリ → 標準ヘッダファイル格納ディレクトリの順で探索
include "aaa.h"
~~~
if/else/elif/endif - 条件付きコンパイル
~~~c
define MODELA 0x01
if MODELA
// モデルAの処理
elif MODELB
// モデルBの処理
else
// 他のモデルの処理
endif
~~~
ifdef/ifndef - 条件付きコンパイル
~~~c:定義があれば有効
define MODELA 0x00
ifdef
// モデルAの処理
endif
~~~ ~~~c:多重インクルードガード
ifndef HELLOWOLRD_H_
define HELLOWOLRD_H_
endif / HELLOWOLRD_H_ /
~~~
error - エラーメッセージ
~~~c
define TABLE_ADDRESS 0x20000000
if (TABLE_ADDRESS % 64) != 0
error "ADDRESS ALIGNMENT ERROR"
endif
~~~
■ 宣言
記憶クラス指定子
auto
- 局所(自動)変数であることを指定
- 一般的には省略
- ブロック内変数のデフォルト記憶域クラス
~~~c
include <stdio.h>
int main() { auto int count = 0; printf("%d", count); } ~~~
static
- 関数、変数宣言時に使用
- 関数の場合、他のファイルからのコールが不可
- 変数の場合、静的変数であることを指定。他のファイルからのアクセスが不可
~~~c
include <stdio.h>
static int countA = 0x01;
int main() { static int countB = 0x02; printf("%d", countA); // OK printf("%d", countB); // OK }
static void sub() // 他のファイルからコール不可 { printf("%d", countA); // OK printf("%d", countB); // ビルドエラー } ~~~
register
~~~c int sub(register int a, register int b) { register int temp = 0;
for(i = 0; i < 10; i++)
{
temp += a + b * i
}
return temp;
} ~~~
extern
- 関数、変数宣言時に使用
- 外部ファイルで定義された関数、変数を参照する際に指定
- 参照側のファイルで定義
~~~c:main.c
include <stdio.h>
// 一般的にはextsub.hとして外部提供関数・変数を定義し、main.cからインクルードする extern int count; extern int sub();
int main() { printf("%d\n", count); // 10 printf("%d\n", sub()); // 20 } ~~~
~~~c:sub.c int count = 10;
int sub() { return 20; } ~~~
typedef
- データ型に対して名前を定義
c:stdint.h
typedef signed char int8_t;
関数指定子
inline
- 関数宣言時に使用
- コンパイラに当該関数のインライン展開を促すための通知
- 関数呼び出しのオーバーヘッド削減になるが、オブジェクトサイズが増加する場合がある
c
inline int sub()
{
return 20;
}
型修飾子
const
- 変数宣言時に使用
- 当該変数が定数である場合に使用し、書き換えるとコンパイルエラーが発生する
c
const int count = 100;
*1:x) / (y