Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

C言語でのヘッダの書き方

スポンサードリンク

f:id:fa11enprince:20150730081939j:plain
よくよく考えてみると真面目にC言語でヘッダの書き方を解説している
書籍ってないなと感じました。
かなり重要な部分なのに、ちゃんと知らない人が多い(自分も含めて)ので、
メモ書きとして残しておきます。
ただし、自分でCを書くことはもうないと思います…。
C++使うし…その場合は必要のないテクニックだし。
ということでC言語におけるヘッダの書き方です。
一応ヘッダの書き方は大きく2つ流儀があると思うのですが、
一つはグローバル変数や共通関数をある程度大きなくくりで
どかっとまとめたものを作るタイプ、
もう一つはヘッダ(.h)のファイルと実装(.c)を分ける流儀です。
現実にはこの中間というようなのもあると思います。
今回はこの中間みたいな形式を想定して書きます。
解説はソースにまとめます。
気を付ける点を箇条書きします。ただし下記の事項はものによっては
必ずしも必須でなかったりします。

気を付ける点

・ヘッダは必ずインクルードガードする。
・グローバル変数が衝突しない工夫をする*1
・個々の実装のヘッダには必要な情報のみ記述する。
・staticな関数は通常.cのほうに記述する。
 逆に.cの内部のみで使うものは全てstaticを付ける。
・構造体も内部で使うものは.cに定義を書く。
他にもありますがそれは参考のリンクに任せることとします。

ソースコード





おまけ(Makefile)

# Makefile

PROGRAM = main.exe
OBJS = main.o a.o

CC = gcc
CFLAGS = -Wall -O4

# suffix rule
.SUFIXES: .c .o

# primary target
$(PROGRAM): $(OBJS)
    $(CC) -o $(PROGRAM) $^

.c.o:
    $(CC) -c $<

.PHONY: clean
clean:
    $(RM) $(PROGRAM) $(OBJS)

Makefileの書き方完全に忘れた。
all書いてないし……。

こうしてみるとC++と違った意味でC言語ってやっぱり難しいよなぁと思います。
あれ?Cって宣言でstatic付けた場合は実装部にstaticってつける必要あったんでしたっけ?
C++はクラスのメンバ関数の実装につけたらエラーになった気がしています。
検証してみたらやっぱりそうだった。

#include <iostream>

using namespace std;

class Hoge
{
public:
    static void hogeFunc();
};

// staticをつけると……
// エラー: 
// cannot declare member function ‘static void Hoge::hogeFunc()’
// to have static linkage [-fpermissive]
// static void Hoge::hogeFunc()
//                           ^
void Hoge::hogeFunc()
{
    cout << "hoge" << endl;
}

int main()
{
    Hoge::hogeFunc();
    return 0;
}

Cの普通の関数(もちろんC++のメンバでない関数)はつけてもつけなくてもコンパイル&リンクは通る……んんん?どっちでもいいのか?そもそもプロトタイプ宣言はCでは必須ではないですし。

*1:SolarisのCCだとextern宣言しなくても同じシンボルの外部変数はコモンセグメントに1つだけ作成してうまくいく