質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

7回答

2405閲覧

C/C++のヘッダーファイルについて

Nippun

総合スコア1147

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2021/05/21 20:55

C/C++のヘッダーファイルは何のために存在しているのでしょうか?用途としての意味は関数やクラスの定義をヘッダーファイルでしていて他のファイルからinculdeできるというのは存じているのですが、最近のプログラミング言語ではヘッダーファイルを書く必要がないのでなぜC/C++では必要なのかといった疑問から質問した所存です。
推測としては当時はコンパイラーがそこまで賢くなっかったため、定義をヘッダーファイルとして書かないと動作しなかったが現在のコンパイラーはそこら辺をうまくやってくれていると思うのですが、どうなのでしょうか?
また、現在のヘッダーファイルを記述しなくていい言語もコンパイラーが内部的にヘッダーファイルを作成しているのでしょうか?
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sigsegv

2021/05/21 21:03

"最近のプログラミング言語","現在のヘッダーファイルを記述しなくていい言語"とは例えば何を指していますか?
takasima20

2021/05/21 21:07

configuration と勘違いしてる?
Nippun

2021/05/21 22:16

Rust等はヘッダーファイルを記述しなくていい言語だと思っています。
guest

回答7

0

ベストアンサー

C/C++ が古い言語だからという理由に落ち着くんだろうと思います。
なぜそう言えるかと言うと、新しい言語でその方式が採用されていないからです。

インクルードは確かに強力で柔軟な機能ですが、強力で柔軟すぎてデバッグを難しくすることがあります。
そこで最近の言語では、型やシグネチャの情報をテキストで読み込むのではなく、ユーザーから隠蔽して提供しています。

インクルードした場合、それはテキストとしてソースファイルの一部になってしまうため、デバッガでそれ以上の追跡ができません。
ユーザーから隠蔽して提供される場合、型情報はソースではなく紛れもない型情報として提供できるため、ツール側の負担が小さくなります。

また、ヘッダをプログラマが書かなければならないということは、同じことを二度書かなければならないことを意味し、どちらかの更新をもう片方と同期させることが人間の責任になってしまいます。ここは自動化できる部分なので自動化するのが望ましいと考える人が多かったのでしょう。
型情報やマクロ定義がごちゃ混ぜになっているヘッダは人間にとっても負担が大きいということです。

投稿2021/05/21 22:35

編集2021/05/21 22:50
Zuishin

総合スコア28662

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

イマドキであれば、潤沢なメモリ領域、強大なCPUパワー、というのを前提として言語設計というのができます
どれだけソースファイルの数があろうと、usingやimportでそのファイルを指定すれば、そいつの言語解析を行い、使うことのできるキーワードのデータベースを作り、何ごともなくコードのコンパイルをしてくれます。

さて、メモリが数十キロバイト(MとかGじゃないよ)、クロック周波数が2MHzの8ビットCPUという環境で、そういう事ができるのかということを考えてみましょう。あるいは、どれだけのことができるのかを考えてみるのがいいかと思います

C言語というのはそういう環境の時代のものです

投稿2021/05/21 23:07

y_waiwai

総合スコア87784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

出遅れてしまいましたが、歴史的なことを知って置いて欲しいので投稿します。

C/C++のヘッダーファイルは何のために存在しているのでしょうか?

分割コンパイルやライブラリ利用の際に発生するインタフェースエラーをコンパイル時に検出するためです。
インタフェースエラーの検出は大きく分けると、コンパイル時、リンク時、実行時の3通りになります。プログラム開発ではなるべく初期の段階でエラーを検出したいという要求があります。

コンパイラは文法の責任は持ちますが、ユーザが定義したソースファイルや第三者が提供したライブラリの情報は持っていません。コンパイラが知り得ないソース情報の整合性をコンパイル時にチェックする方法の一つが変数の型や関数の型の宣言を格納したヘッダーファイルです。

歴史的に見ると、1954年に開発されたFORTRANには、当初は分割コンパイルとという概念はありませんでした。ライブラリもなく、必要な機能はコンパイラに組み込まれた文や関数だけしか使えませんでした、1959年に開発されたCOBOLや1964年に開発されたBASICも同じような感じだったと思います。
その後、ファイルを分割して分割コンパイルとリンクという概念が出てきましたが、変数の型や関数の引数や型を合わせるのはプログラマの責任でした。

1970年開発のPASCALや1072年開発のCは、宣言によって変数の型や関数の引数や型の不整合をコンパイル時にチェックできるようにしました。

これに代わる方法としては、プロジェクトファイルなどでソースを管理するとか、インターネットにライブラリ情報を置いておいてそれを読み込むとか、リンク時に型情報をチェックするとかいろいろな方法があるでしょう。

投稿2021/05/22 01:41

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

「賢い」という言葉が適切かどうかとは思いますが、C言語が開発された1970年代に思いを馳せてみると...今と比べて格段に
・遅いCPU
・少ないメモリ
・容量小さく遅いストレージ
で処理されていたわけです。その制限下でどうやってそこそこのサイズのプログラム群を処理するか...答え「人海戦術」。

そもそものC言語のソースの構造を考えてみてください。あるソースで注目している時点に登場するシンボルは、そのシンボルに意味を与える宣言か、既に宣言された(あるいは予約語)もののみ、です。コンパイラは、既に知っているシンボルだけを処理すればいいようになっていますね(関数は宣言を仮定しちゃうという荒業もありますが)。そのほうがコンパイラの作りが簡単になるでしょう。で、宣言が先に出てくるように気を遣うのは「プログラマの責任」ということにすれば万事解決。それがCのポリシーなんだから、同意できない奴は使うな、ということで。

では、ファイル分割した他のファイルのシンボルはどうやって知りましょう? ストレージはこんなに小さくてアクセスが遅くて、メモリはこんなに狭いのに、コンピュータがすべてのファイルを解析してシンボルのリストを作る? いやぁ、大変だから、そういうのもプログラマに丸投げ。プログラマが、他のファイルの情報を切り出して宣言を集めたヘッダファイルを作ってください。本質としてヘッダファイルの情報ってのは定義のあるソースファイルと全く重複しているんですけど、プログラマは神なんだから世界の有り様は全部管理して。必要なヘッダの取り込みなんてのもプログラマが指示してね。

つまり、(当時の)コンピュータがやるのが大変そうなところを人間が手作業でやることにしたのが「ヘッダファイル」というシステムなんだ、と勝手に理解しています。

先にそういうシステムができてしまえば、後付で利点を探す動きもあるでしょうけど...やっぱりそんなのは本来人間がやる仕事じゃなかったわけで、他の回答にもあるように、最近の言語では分割したファイルの中身にまで関わる情報を人間が管理するなんてことはもうあり得ないでしょう。

Cって原始的、ですよね。
Cを学ぶとコンピュータのことがよくわかります! ですか? そうでしょう。今どきならコンピュータがやればいいようなことも人間が肩代わりするんですから。

投稿2021/05/21 23:27

thkana

総合スコア7652

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

一部私の私見が混ざっていますが

C/C++の世界では宣言と定義の区別が大きいからだと思います。このため、宣言部をヘッダとして独立化させる意義が大きいです。宣言だけであれば(矛盾ない範囲で)重複することができるので多重インクルードを気にせず利用できます。例えば、グローバル変数は名前空間(定義が適用される範囲)が広く、一箇所で使用されただけで他の部分に影響を与える可能性があります。

例えばjavaの場合では事実上、定義は宣言を兼ねており区別が不要です。また、パッケージの概念のおかげで、名前空間が分割されます。

投稿2021/05/21 21:48

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nippun

2021/05/21 23:01 編集

なるほどです。 矛盾がない限り柔軟に宣言ができるというわけですね。 ありがとうございます。
HogeAnimalLover

2021/05/21 22:34

え?私は「javaの場合はそもそも分離不要である」という意味で書いたのですが。
Nippun

2021/05/21 22:55

そういう意味で解釈しています。書き方が悪かったです。すみません。
Kenji.Noguchi

2021/05/25 00:46 編集

質問者さんへの補足ですが、Cで多重インクルードを気にせず利用できるのは、ヘッダーファイルを書いたプログラマがインクルードガードをきちんと実装しているからです。普段なんの気なしに利用しているヘッダーファイルは、その内部で#ifndef HEADERFILE_H #define HEADERFILE_H .... #endifと言うようなマクロか#pragma onceなどがあるはずです。二回目以降のincludeではプリプロセッサがマクロ展開時にその部分を飛ばすので二重定義エラーが起きないわけです。
guest

0

なぜ、C, C++にヘッダーファイルがあるかと言うとC, C++を設計した人が便利だと思って作ったから。
なぜ、最近の言語にヘッダーファイルがないかと言うと「なんでヘッダーファイル書かなきゃならんの?めんどくさい。」と思った人が多かったからなくなった。
それだけのことです。

もうちょっと補足します。
C言語の設計者が作った機能は #include という非常に便利な機能だけです。
これは例えば次のような使い方も出来ます。(コンパイル実行確認済)

HelloAnotherDimensionOfTheWorld.txt

txt

1void HelloAnotherDimensionOfTheWorld() 2{ 3 std::cout << "Hello Another dimension of the World!\n"; 4}

HelloAnotherDimensionOfTheWorld.cpp

C++

1#include <iostream> 2#include "HelloAnotherDimensionOfTheWorld.txt" 3 4int main() 5{ 6 HelloAnotherDimensionOfTheWorld(); 7 8 return 0; 9}

これを曲解した利用者が、まず#includeするのは拡張子".h"のファイルだけにしましょうというルールから始まって、様々なルールで縛り付けて使いにくくした結果「ヘッダーファイル書くのめんどくさくね?」って意見が多数を占めるようになり、#include という非常に便利な機能も闇に葬られたわけです。

早くも2つも低評価が付いていますが、まぁ#include の機能の便利さを曲解して様々なルールで縛り付けて使いにくくしている代表者のような方々でしょう。C言語と言うものは本来非常に緩いルールで自由に書けるものです。

投稿2021/05/21 23:03

編集2021/05/22 00:19
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2021/05/22 00:15

現時点でスコア-276の方にコメントするのもなんだかなぁ、と思いつつ。 例示した#includeの使い方のどこが便利なのでしょう? Hello~.cとHello~.hに分けて定義を.cに、宣言を.hに書くのに比べて手数が少ないというのは言えますが「便利」とは違うような。 その#includeの使い方をすると、Hello~.cppの依存はHello~.txtに張られるわけですよね。つまり、表示するメッセージの最後の"!"を"!!"にしたとき、.cpp(もしかしたら巨大なmain関数を書くやつがいるかもしれない)が再コンパイルとなりますね。なんのためにファイルを分けたのでしょう? まぁ、自由すぎる機能は混乱を招き、ルールで縛ろうとすると「オレは嫌だ」という一派が出てくるというのはよくあることですが。 自由を謳歌するならいっそのこと Hello~.txt --- "Hello Another dimension of the World!\n" --- Hello~.cpp --- int main() { std::cout << #include "Hello~.txt" ; } としたほうがイッちゃっててよくないですか?
退会済みユーザー

退会済みユーザー

2021/05/22 00:22

それでコンパイル通るなら、そっちの方がカッコいいですね。
thkana

2021/05/22 00:23 編集

あ、別にいうほどのことじゃないですけど、私はteratail_dayoさんを低評価したことはありませんので。
maisumakun

2021/05/22 00:35 編集

> C言語の設計者が作った機能は #include という非常に便利な機能だけです。 IOCCCのような芸術作品としてのコードを作るのならさておき、実用的なコードを書く上で関数「定義」の#includeはどのような面で有用だとお考えでしょうか? 文法的にはどんなことでも可能ですしコンパイルは可能ですが、外部スコープを持つ同じ関数定義が複数あるとリンクエラーとなるので、複数箇所で関数定義が書かれたファイルを#includeすることは、事実上不可能です。 (回答者の意図が「芸術的な書き方もできる」という意味での自由だったようですが、とりあえずコメントは残しておきます)
退会済みユーザー

退会済みユーザー

2021/05/22 00:25

あと私が便利だと言ってるのは#includeと言う機能のことであってその使い方を便利にするのも不便にするのも利用者次第です。
maisumakun

2021/05/22 00:34

「ひねくれた書き方をできる」という意味で「自由に書ける」というのは、確かに間違ってはいないです。 ただ、大多数のプログラマーは「正常に動くコード」にしか興味がないので、そういった人には「自由度が高すぎる」のはむしろデメリットにしかならないです。
thkana

2021/05/22 00:39

> 私が便利だと言ってるのは#includeと言う機能のことであって なら、便利じゃない例ではなく、便利な使い方の例を挙げていただければと思います。
退会済みユーザー

退会済みユーザー

2021/05/22 01:11

Hello Another dimension of the World! この言葉が全てです。 翻訳して下さい。
thkana

2021/05/22 01:19

なるほど、次元が違って比較不可能ということですね。スコア(さらに伸びて)-280にも納得です。
退会済みユーザー

退会済みユーザー

2021/05/22 03:44 編集

少々自己紹介をします。 元々、絵が得意で絵描きになるのが夢でした。 母に連れられて美術館にもよく足を運びました。 小学生の頃ですかね。ピカソ展に行きました。 そこで衝撃的な絵を見ました。 有名なピカソのぐちゃぐちゃの絵ではありません。 小学生の自分と同じ年ごろの子供が描いた絵です。 そう、幼少のピカソが描いた絵です。 本当に衝撃的な芸術的なスケッチでした。 あれを見て絵描きになる夢はあきらめました。 到底敵わないと。絵描きになる子供の夢を打ち砕くには最高の絵でした。 当時、算数においては某政令指定都市の№1, 2を争う学力を持っていた自分がその後目指したのはプログラマーでした。 無意識のうちにピカソの絵のようなソースコードを目指している気がします。 先程のサンプルをコンパイルしてみました。 確かにコンパイルは通るし実行も出来ます。 でも、ピカソの絵とは違います。 ピカソの絵は「自分には本当にこう見えるからそのまんま描写したらこうなった。」と言うものです。 thkanaさんのソースコードはピカソの絵を真似てただぐちゃぐちゃにしてコンパイルを通しただけのソースコードに見えます。 それでは私のようなハイスコアを取ることは出来ません。
thkana

2021/05/22 04:25

ハイスコアを狙って書いたようにみえるというのは意外でした。そんなにすごかったのか。 俺って才能あるのかな。狙って書いたらいいのかな。 おっしゃるとおり。あれは#includeを変につかって書いたぐちゃぐちゃの落書きです。ピカソも真似ていません。子供に付き合ってお絵かき遊びをした程度のつもりです。こんなぐちゃぐちゃが描けるんだって。それでカケラでも芸術性の評価をされるとは、びっくり。
episteme

2021/05/22 04:28

自己紹介ならプロフィールに書いておくれ。
Zuishin

2021/05/22 04:38

とりあえずピカソに謝れとしか。
退会済みユーザー

退会済みユーザー

2021/05/22 05:31

Zuishin さん 私の回答とあなたの回答。 ほとんど意味は同じですよ。 同じモデル(質問)を同じように描写(回答)しただけなのにね。 あなたの回答が写真だとすると私の回答がピカソの絵に見えてきませんか?
退会済みユーザー

退会済みユーザー

2021/05/22 05:32

thkana さん ここで狙うのはいつでもベストアンサーを狙って下さい。
Zuishin

2021/05/22 05:32

ほとんど同じだと言うなら私にも謝れ。
退会済みユーザー

退会済みユーザー

2021/05/22 05:35

写真家によるピカソへの批判と受けとめておきます。
thkana

2021/05/22 05:42

ここはコメント欄なのでベストアンサーはありません。
退会済みユーザー

退会済みユーザー

2021/05/22 05:45

はい。 わかりました。
退会済みユーザー

退会済みユーザー

2021/05/22 05:51

Zuishin さん もうちょっと言わせてもらうと私の回答はあなたの回答を見て「あぁ、ベストアンサー出ちゃってるな、書くことないや。」と思ってしばらく考えた後、あなたが写した写真(回答)を見ながら模写したものです。そう考えると本当にピカソの絵のように見えてきませんか?
Zuishin

2021/05/22 05:52

下手くそすぎて全く。とりあえずピカソに謝れ。
guest

0

現在のヘッダーファイルを記述しなくていい言語もコンパイラーが内部的にヘッダーファイルを作成しているのでしょうか?

そう考えて差し支えありません。
コンパイル時 Javaなら.class, .NETだと.dll が生成されますが、その中にメタデータ(ヘッダに相当するもの)が埋め込まれます。

メタデータが埋め込まれる分ファイルがデカくなり、(Cが生まれた当時の)昔々の環境には荷が重い。

投稿2021/05/22 01:37

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問