4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

忘れがちなC言語

Last updated at Posted at 2017-12-03

■ プリプロセッサ

define - プリプロセッサマクロ定義

# include <stdio.h>
# define COUNT                  0x5
# define MULTIPLE_COUNT         (2 * COUNT)
# define DEVIDE_COUNT(x, y)     ((x) / (y))

int main()
{
    printf("%d\n", COUNT);
    printf("%d\n", MULTIPLE_COUNT);
    printf("%d\n", DEVIDE_COUNT(9, 2));
}
実行結果
5
10
4

既定義マクロ

# 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__);
}
実行結果
LINE : 5
FILE : test.c
DATE : Dec  1 2017
TIME : 00:00:00

undef - マクロ定義削除

# define COUNT      0x5
# undef  COUNT

# - 文字列化演算子

マクロ引数をダブルクォーテーションを付けた文字列に変換する

# 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));
}
実行結果
COUNTB
0x06

## - 文字列連結演算子

# include <stdio.h>

# define COUNTB    0x6
# define COMBINE_COUNT(x, y)    x ## y

int main()
{
    printf("%d\n", COMBINE_COUNT(COUNT, B));
}
実行結果
6

include - ファイルインクルード

// 標準ヘッダファイルのインクルード
// 標準ヘッダファイル格納ディレクトリのみ探索
# include <stdio.h>

// 作成ヘッダファイルのインクルード
// カレントディレクトリ → 標準ヘッダファイル格納ディレクトリの順で探索
# include "aaa.h"

if/else/elif/endif - 条件付きコンパイル

# define MODELA   0x01

# if MODELA
    // モデルAの処理
# elif MODELB
    // モデルBの処理
# else
    // 他のモデルの処理
# endif

ifdef/ifndef - 条件付きコンパイル

定義があれば有効
# define MODELA   0x00

# ifdef
    // モデルAの処理
# endif
多重インクルードガード
# ifndef HELLOWOLRD_H_
# define HELLOWOLRD_H_

# endif /* HELLOWOLRD_H_ */

error - エラーメッセージ

# define TABLE_ADDRESS   0x20000000

# if (TABLE_ADDRESS % 64) != 0
# error "ADDRESS ALIGNMENT ERROR"
# endif

■ 宣言

記憶クラス指定子

auto

  • 局所(自動)変数であることを指定
  • 一般的には省略
  • ブロック内変数のデフォルト記憶域クラス
# include <stdio.h>

int main()
{
    auto int count = 0;
    printf("%d", count);
}

static

  • 関数、変数宣言時に使用
  • 関数の場合、他のファイルからのコールが不可
  • 変数の場合、静的変数であることを指定。他のファイルからのアクセスが不可
# 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

  • 仮引数または局所変数の宣言時に使用
  • アクセス時間最適化のため、コンパイラへレジスタ割り付けのヒント情報を与える
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

  • 関数、変数宣言時に使用
  • 外部ファイルで定義された関数、変数を参照する際に指定
  • 参照側のファイルで定義
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
}
sub.c
int count = 10;

int sub()
{
    return 20;
}

typedef

  • データ型に対して名前を定義
stdint.h
typedef signed char        int8_t;

関数指定子

inline

  • 関数宣言時に使用
  • コンパイラに当該関数のインライン展開を促すための通知
  • 関数呼び出しのオーバーヘッド削減になるが、オブジェクトサイズが増加する場合がある
inline int sub()
{
    return 20;
}

型修飾子

const

  • 変数宣言時に使用
  • 当該変数が定数である場合に使用し、書き換えるとコンパイルエラーが発生する
const int count = 100;
4
8
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?