- ベストアンサー
C言語の分割ファイル先の関数呼び出しについての問題点と改善点
- C言語でファイルを関数ごとに分割した場合の関数呼び出しについての問題点と改善点を紹介します。
- 通常、関数を呼び出す際にはプロトタイプ宣言を使用しますが、分割ファイルの場合はどのように宣言すれば良いのでしょうか。
- include文を使用する方法もありますが、一般的には別の方法が推奨されます。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
自分はfunction関数を含む静的オブジェクトもしくはライブラリを作成します。 main関数に外部関数を定義したヘッダファイルをincludeさせてビルドします。 そしてファイルが正常にコンパイルとリンクがされるようにプロジェクトを作成します。 ------------- ファイルがメインとそれ以外の二つだけなら質問のような方法でもとりあえずは動きます。 しかし関数呼び出しとファイル構成が複雑になると面倒になります。 例えばファイルがメインと関数1、関数2、関数12の4個あり、 main -- fun1 -- fun12 ......+ fun2 -- fun12 のようにmainからfun1とfun2がコールされ、fun1とfun2の両方でfun12をコールしたとします。 includeを利用するとmain文の前にfun12、fun1、fun2の順番でincludeする必要があります。 ファイルと関数がさらに増えたらincludeの順番を注意する手間が増大します。 そういう面倒な処理はコンピュータ(コンパイル環境)にまかせるべきで、人間は正しい関数定義をmainに教えるだけにすべきです。 他に考えられる問題点としてincludeしたファイル内にあるdefineやincludeによってはinclude先の関数になにかしら影響を与える可能性があります。 例えばincludeしたファイル内で「#define TRUE 0」としていて他のファイルでは「#define TRUE 1」としていたら二重定義でコンパイルエラーになります。 コンパイルエラーや問題になったら処理を見直せばいい話ではありません。 コンパイルエラーや他の関数の処理に影響を与えないようファイルや関数は独立するように適切な記述をし、環境を構築して下さい。 ファイルや関数がきちんと独立していればそれらは他のプログラムでもそのままの形で流用できます。 流用できないのであればファイルや関数を独立させる意味が半減してしまいます。
その他の回答 (3)
- kmee
- ベストアンサー率55% (1857/3366)
> main文と同じファイルにある関数は,main文より上に記述している場合は > プロトタイプ宣言で呼び出すことが出来ますが すみません。 質問を一通り読むと、思いちがいがあるような気がして。 「プロトタイプ宣言」と「関数の定義」はちゃんと使いわけていますか? プロトタイプ宣言は、関数の戻り値や引数の型等だけを宣言するものです。 int function(int a,int b) { functionの内容 } という関数の定義だったら、プロトタイプ宣言は int function(int a,int b) ; となります。 プロトタイプ宣言は、その関数を使用する前にする必要があります。 プロトタイプ宣言されていたら、関数の定義は、ファイルの最後でも、別ファイルでもかまいません。 関数の定義はプロトタイプ宣言も兼ねているので、使用する前に関数の定義があれば、単独のプロトタイプ宣言は無くてもいいです。 例1:プロトタイプ宣言の使用 /* functionのプロトタイプ */ int function(int,int) ; /* 変数名は省略可能 */ /* functionを使用する関数function2の定義 */ int function2(int c,int d) { .... ret=funtion(c,d); .. } /* functionの定義 */ int function(int x,int y) { /* プロトタイプと引数の数と型、戻り値の型があってれば、引数の名前は変更可能 */ .... } 例2: 先に関数を定義 /* functionのプロトタイプ */ /* int function(int,int) ; */ /* あってもなくてもよい*/ /* functionの定義 */ int function(int x,int y) { .... } /* functionを使用する関数function2の定義 */ int function2(int c,int d) { .... ret=funtion(c,d); .. } /* なお、「main『文』」ではありません。「main『関数』の定義」です main関数は、実行時に最初に呼ばれる、ということ以外は他の関数と同じです。 */ 常套手段は次の通り ・共通する関数のプロトタイプをヘッダファイルとしてまとめる。 ・ソースファイルで #include "上記ヘッダファイル" として、宣言を組込む ・分割コンパイル→リンクで実行ファイルに 実は、あなたは「別ファイルで定義されている関数を利用する」というのを、C言語の現況の最初のころから使っているはずです。 「おまじない」として #include <stdio.h> 等としているかと思います。 この stdio.h というが、ヘッダファイルです。その中身はプロトタイプ宣言が中心です。 printf等の関数は、別ファイルに書かれて、予めコンパイルしておいたものが使われます。
お礼
返事が遅れてしまい,大変申し訳ありません. 回答ありがとうございます. >なお、「main『文』」ではありません。「main『関数』の定義」です すみません. 仰る通り,main『関数』ですね. よく間違えます.おそらく,学校で先生が「main文」と言っていたからだと思います(笑) >常套手段は次の通り ・共通する関数のプロトタイプをヘッダファイルとしてまとめる。 ・ソースファイルで #include "上記ヘッダファイル" として、宣言を組込む ・分割コンパイル→リンクで実行ファイルに 丁寧にありがとうございます. 大変勉強になりました. また,質問文で迷わしてしまったようで申し訳ありません. 「プロトタイプ宣言」と「関数の定義」は使い分けているつもりですが,回答の文を読ませて頂いて,改めて整理され勉強になりました. ありがとうございました.
- php504
- ベストアンサー率42% (926/2160)
プログラムでprintf( )関数とか使いますよね どこにも定義してないのになぜ使えるのでしょう printfは標準関数だから特別というわけではありません これはstdio.hというヘッダをincludeしているからです 自作関数の場合も同様にヘッダファイルにプロトタイプ宣言を書いてincludeするのが一般的です -----function_file.h int function( int a, int b); -----function_file.c int function( int a, int b) { return a + b; } -----main_file.c #include "function_file.h" int main(void) { int c; c = function( 1, 2); . . . あとこの場合は出来たオブジェクトファイルをリンクしないといけません
お礼
返事が遅れてしまい,大変申し訳ありません. 回答ありがとうございます. >自作関数の場合も同様にヘッダファイルにプロトタイプ宣言を書いてincludeするのが一般的です 学校では「stdio.hはおまじないだから気にしないで~」という話が最初にあり, 自作関数を作ったら「プログラムの最初にプロトタイプ宣言というものを書けばmain関数を前にもってこれて綺麗に書けるよ~」とかこういう風に習いました. 今,やっと僕の中でヘッダファイルの位置付けがはっきりした気がします. 初めから「ヘッダファイルにプロトタイプ宣言を書いて」と教えてくれればいいのにと思いました(笑) ありがとうございました.
- Tacosan
- ベストアンサー率23% (3656/15482)
プロトタイプ宣言を書いたヘッダファイルを作って #include, 最後にリンク が「一般的」でしょうな.
お礼
返事が遅れてしまい,大変申し訳ありません. 回答ありがとうございます. 勉強になりました.
お礼
返事が遅れてしまい,大変申し訳ありません. 回答ありがとうございます. >includeを利用するとmain文の前にfun12、fun1、fun2の順番でincludeする必要があります。 なるほど. "fun1とfun2の両方でfun12をコール"する場合,fun12が先に書かれている(コンパイルされている)必要があるのですね. また,定義の問題もなるほどと思いました. 本当に勉強になりました. ありがとうございました^^