既に解決済みですが、ちゃんと理解された方が良いと思うので。
まだ簡単なプログラムを書いておられると思いますが、これから規模が大きくなり複数のソースファイルを使ってコンパイルする様になった場合、別のソースファイルから関数 test を参照したいという事が出てくるはずです。
こういった場合プロトタイプ宣言をヘッダファイルに含ませておき、test を使うソースファイルから include します。
その際に extern という識別がある事に注意して下さい。
c:test.h
1/* test.h */
2extern int test();
c:test.c
1/* test.c */
2#include "test.h"
3
4...
extern はその宣言を参照するソースファイル上には test の実態は存在しないという意味になります。質問者さんのソースファイルには extern がありませんが、それは test の実態がそのソースファイルに存在するので正しい使い方です。
なおここまで書きましたが関数の場合には実は extern が付いていなくてもエラーにはなりません。つまり test が存在するソースファイルから extern が付いていない宣言を含む test.h を include してもエラーにはなりません。変数の場合には、複数のソースコード上にグローバル変数が存在する事になりリンク時にエラーとなるはずです。
これと異なり static という識別もあります。
これは逆にそのソースコード内で出現する test は、そのソースコード上でのみ有効という働きになります。ですのでヘッダファイルで切り出さずソースファイル(.c)内で宣言します。これを付けずに複数のソースファイル上で同じ関数名の実態を実装するとリンク時にエラーになります。
話を戻して、このヘッダファイルによるプロトタイプ宣言は分割コンパイル時に使われる常套手段で、Makefile と併用すると威力を発揮します。
makefile
1all : foo
2
3foo : foo.o test.o
4 gcc -Wall -o foo foo.o test.o
5
6foo.o : foo.c test.h
7 gcc -Wall -c foo.c
8
9test.o : test.c test.h
10 gcc -Wall -c test.c
11
12clean :
13 rm -f *.o
14 rm -f foo
この様に、foo.c にも test.c にも依存として test.h を含ませておくことで、関数 test に引数を足したくなった場合に未然にエラーを防げる事になります。
例えば test.h や test.c だけ修正してコンパイルすると気付かなかった foo.c の変更がエラーになってくれる訳です。
2018/01/05 00:29
2018/01/05 01:28
2018/01/20 09:38