関数の定義というのは、その関数がどのような振る舞いか書いたもののことです。 つまり、こんなやつが関数fooの定義です。 つまり普段見ている関数の実体のことです(decl_func0.c)。
double d_max(double a, double b) { if(a < b) return b; else return a; }じゃあ、宣言というのは何かというと、その関数をどのように使えばいいか、 その型情報を記述したものです。 プロトタイプ宣言 とも呼ばれます。
double d_max(double, double); /* extern double d_max(double, double); と書くのもOK */ /* double d_max(double a, double b); と引数まで書くのもOK */ /* double d_max(); 引数の宣言は行わなくても一応OK */さて、宣言しないとどんな事があるか試してみましょう。 利用する側(decl_func1.c)は、これだけ。
int main(int argc, char** argv) { double val = d_max(1.0, 2.0); printf("d_max(1.0, 2.0) = %f\n", val); return 0; }コンパイルするのは、こんな感じ。
kamada@cygwin% gcc -c decl_func0.c kamada@cygwin% gcc -c decl_func1.c kamada@cygwin% gcc -o decl_func decl_func0.o decl_func1.oで、実行するとこんな感じ
kamada@cygwin% ./decl_func d_max(1.0, 2.0) = 256.000000 /* 例えばこんな結果がでる */嫌な結果です。詳しいことは説明しませんが、これは、d_max() という関数が int を返す関数だとおもってコンパイラが処理してしまった結果です。 これだけ短いプログラムだと原因に気がつくのもすぐでしょうが、 大きなプログラムでこの手の間違いがあると悲惨です。で、こんなトラブルを避けるために コンパイラの警告(Warning)レベルを上げましょう。
kamada@cygwin% gcc -Wall -c decl_func1.c decl_func1.c: In function `main': decl_func1.c:2: warning: implicit declaration of function `d_max' decl_func1.c:3: warning: implicit declaration of function `printf'implicit declaration つまり、暗黙的な宣言がつかわれたよといっています。 明示的(explicit)な宣言がないという警告です。で、これに気づいてプロトタイプ宣言 を行ったのが、decl_func2.cです。 冒頭に
#include <stdio.h> double d_max(double, double);の2行が加わりました。実行するとこんな感じ。
kamada@cygwin% gcc -c decl_func2.c kamada@cygwin% gcc -o decl_func decl_func0.o decl_func2.o kamada@cygwin% ./decl_func d_max(1.0, 2.0) = 2.000000今度の結果は happy です。
#ifndef __DECL_FUNC0_H__ #define __DECL_FUNC0_H__ /* 上の 2 行はおまじない */ double d_max(double, double); /* 最後の行もおまじない */ #endif /* !define(__DECL_FUNC0__) */前後におまじないが入っていますが、 その理由を知りたい人はこちらをみましょう。
ということで「利用する側」も、
#include "decl_func0.h"と書くだけで、プロトタイプ宣言を取り込めるようになりました。
実は、みなさんが普段良く使う
#include <stdio.h> #include <stdlib.h>の中身も、このようなプロトタイプ宣言などをまとめたファイルです。詳しいことは、こちら。
man 3 printf(q で終了)などとすることで、その関数の使い方が表示されます。 その中に、どの header file を取り込めば良いかも載っていますので、 見てみましょう。sin, cos などの使い方が分かるはず。
2001.10.29/ Tomio KAMADA: kamada@cs.kobe-u.ac.jp