dポイントプレゼントキャンペーン実施中!

今までは、Webプログラミングを行っていたのですが、
最近になって、C++の仕事を請け負いましたので、
C++を勉強しつつ、プログラムをしていたのですが、
Webプログラムとの違いに悩んでいる部分があります。

それは、ヘッダファイルとソースファイルの関係についてです。

ほかのファイルから、インクルードされたヘッダファイルが、
読み込まれるというのは納得がいくのですが、
そのヘッダファイルに関連付け(?)られたソースファイルも、
一緒に読み込まれるという理由がわかりません。

ヘッダファイルでソースファイルを読んでいるような記述もないような感じなので、とても疑問に思っております。

なぜ、ヘッダファイルをインクルードしただけで、付属のソースファイルも読み込まれるのでしょうか?

A 回答 (3件)

> main.cppを起動した時に、kansuuのヘッダファイルしか呼んでいないのに、kansuu.cppの処理内容「あいうえお」がしっかりと表示されてしまうのはなぜなんでしょうか?



結論から言うと、実行ファイルの中にkansuu.cppをコンパイルしたものも入っているからです。

printf()の話と同じことなのですが、kansuu.cpp, main.cppをコンパイルすると、それぞれに対応したオブジェクトファイルというものが作られ、さらにそれらのオブジェクトファイル全部と標準ライブラリなどを全てくっつけて(リンクして)、最終的な実行ファイルが作られます。
逆に言うと、オブジェクトファイルをくっつけてないとソース内でヘッダをincludeしていても「関数がありません」のようなコンパイルエラーになります。

この、どのオブジェクトファイルをリンクするか、というのは実行ファイルを作る最終段階のコンパイラ実行(実際にはリンカというプログラムの実行)のときに指定します。
もしかしたら指定している意識がないのかもしれませんが、どこかで指定しているはずです。
統合開発環境ならソース追加で自動的に設定してくれることがあります。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

なるほど!今までは、すでに整っている制作環境でプログラムを行っていたために、指定しているという意識がなかっただけで、
実際は、PHPでSmartyのパスを指定するように、リンクするパスを指定している場所があるんですね。

納得致しました。
どうもありがとうございました!

お礼日時:2008/06/03 17:28

#1さんと同じで、期待している答えが何かが分かりづらいのですが...



ヘッダファイルをインクルードした場合、読み込まれるのはあくまでもそのヘッダファイルだけです。ただし、読み込んだヘッダファイルの中に#includeがあれば、それらも読み込むことになります。

もし、printf等がヘッダ(この場合は「ヘッダファイル」ではなく「ヘッダ」)をインクルードするだけでなぜ使えるかということであれば、実際にはヘッダをインクルードする必要さえないのです。

namespace std {
int printf(const char* ...);
}

としてやれば、規格に合致した処理系であればstd::printfが使えます(多くの処理系は規格に完全に合致していませんが、処理系不明なので正確なアドバイスはできません)。
あとはコンパイル時の設定(オプションなど)しだいですが、これも処理系不明なので正確なことはいえません。普通は、標準関数は何も指定しなくても勝手にリンクされます。

ところで、

> Webプログラムとの違いに悩んでいる部分があります。

とのことですが、C++でもWebプログラミングは可能です。
これまで使っていた言語を補足していただけると、もう少し的確な回答ができるかと思います。それから処理系も。
    • good
    • 1
この回答へのお礼

#1さんと同様に早速のご回答ありがとうございます。

質問内容の分かりづらさについてはすいませんでした。

#1さんのお礼に、もう少しわかりやすいように、
再度ご質問をさせて頂きましたので、
そちらを見て頂けますでしょうか?

>これまで使っていた言語を補足していただけると、もう少し的確な回答ができるかと思います。それから処理系も。

Webプログラムは、PHPとSmartyを使って行っておりました。

今回のような状況ですと、
PHP+Smartyの場合は。

main.php
---------------------------------------
<?
$smarty->display("main.tpl");
?>
---------------------------------------

main.tpl
---------------------------------------
<form action="main.php">
<input type="submit" value="移動">
</form>
---------------------------------------

上記のような感じで、次の処理を呼び出す場合は、
どこを呼び出すかがソース上に書いてあるため、わかりやすいのですが・・・

お礼日時:2008/06/02 12:02

えーと例えば、stdio.hをincludeしたら、なぜソースにないprintf()が使えるのかわからない、ということでしょうか。



コンパイラで何のオプション指定もしないで単に実行ファイルを作るだけ、という場合、コンパイラが自動的に標準ライブラリというものをくっつけて(リンクといいます)くれるからです。
この場合、printf()の記述されているソースファイルが読み込まれているわけではありません。標準ライブラリの中にすでにコンパイル済みのprintf()が入っています。

もしも標準ライブラリにない関数を使う場合にはコンパイラのオプションでこれこれのライブラリをリンクする、と教えてやらなければなりません。

所望の答えでしょうか?
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます。

質問内容がわかりずらかったようで、
すいませんでした。

例として、

kansuu.h
--------------------------------------------
void kansuu1( void ); // 関数の宣言のみ行う
--------------------------------------------

kansuu.cpp
--------------------------------------------
void kansuu1()
{
printf("あいうえお");
}
--------------------------------------------

main.cpp
--------------------------------------------
#include "kansuu.h"

kansuu1();
--------------------------------------------
(stdio.hなどの処理に必要なインクルードは省略)

上記のような感じで、
main.cppを起動した時に、kansuuのヘッダファイルしか呼んでいないのに、kansuu.cppの処理内容「あいうえお」がしっかりと表示されてしまうのはなぜなんでしょうか?

お礼日時:2008/06/02 11:53

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!