
#include
で最初に含むファイルっていったい何者なんでしょうか?
rand()を使うにはstdlib.hをインクルードしますし、printfのような入出力関係にはstdio.hを、文字関係ならstring.hを・・。
それはわかるのですが、これは、それぞれのヘッダファイルに自作関数の集合のようなものが入っていると考えるのは間違いなんでしょうか?
例えば、strcpyを使用するにはstring.hをインクルードするべきですが、
それはstring.hの中に
char *strcpy(char *s1, const char *s2)
{
char *p = s1;
while (*s1++ = *s2++)
;
return (p);
}
みたいな記述が入っていると想像するのは間違いですか?
自作関数を集めてヘッダファイルにする事出来ますけど、これらは違うんですか?
これだとprintfとかどうやって実装しているんだって思ってしまって・・。
直接stdio.hを開いてみたものの意味不明で、其の中にさらにある.hファイルも開いてみましたがよくわかりませんでした・・。
すみませんが、よろしくお願いします><
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
★追記。
・昔、買った本の中にC関数の実装例が載っていたものがあったので紹介します。
http://www.amazon.co.jp/dp/4774104329/→『新ANSI C言語辞典』
ただし、CD-ROM が 8 cmの小さいタイプですのでデスクトップ型パソコンでは、
本体を横置きにしないとマズイです。注意!
・今でも買えるようなのでお財布と相談して購入などをしてみてはどうでしょうか。
・以上。わおり。
参考URL:http://www.amazon.co.jp/dp/4774104329/
No.4
- 回答日時:
> しかしそうなるとprintfはどうやって書かれているんだ・・と思うのですが、各標準関数はどのように実装されているのかその中身を見る事はできますか?
処理系によってはソースが付いてくるかと。
VCの場合だとインストール時に選択できる場合があります。
「crt ソースコード」とかそんな感じで。
Linuxとかなら、ライブラリのソースがあるはずです。
No.3
- 回答日時:
まず根本的なところから...
#includeの後に指定するヘッダ名が、"..."の形式か<...>の形式かによって意味が異なります。"..."の場合は、その名前のソースファイルを探索し、見つかった場合はそのファイルを取り込みますが、見つからなければ<...>と同じように振る舞います。<...>は処理系の標準ヘッダを取り込みます。標準ヘッダはファイルとは限りません。ただし、大多数の処理系の場合はファイルですので、一度そのファイルをじっくり調べてみることをお勧めします。
ヘッダ(またはヘッダファイル)の中には、通常、型やマクロの定義および外部変数や関数の宣言が含まれていますが、場合によっては関数の定義が含まれていることもあります。具体的にはインライン関数であったり、C++の場合は関数テンプレートであったりするわけです。
> これだとprintfとかどうやって実装しているんだって思ってしまって・・。
printfの場合、stdio.hの中には、
int printf(const char*, ...);
という関数の宣言があるだけです。
関数の実体は、
#include <stdio.h>
#include <stdarg.h>
int printf(const char *format, ...)
{
va_list ap;
int count;
va_start(ap, format);
coount = vfprintf(stdout, format, ap);
va_end(ap);
return count;
}
のようになっています。(vfprintfの代わりにvprintfかもしれませんが...)
#2の回答のように、vsprintfを使うと出力文字数に制約ができるため、printfの仕様を満たすことができません。
この関数は、通常、あらかじめコンパイルされてバイナリ形式で処理系が持っており、リンク時にくっつけられます。
Cの場合、上のprintfと同じように、外部で関数の実体が定義された上で、ヘッダ内でマクロとして別途定義される場合があります。例えば、abs関数のような単純なものの場合、
int abs(int j)
{
return j < 0 ? -j : j;
}
という外部定義の他に、
int abs(int);
#define abs(j) ((j) < 0 ? -(j) : (j))
というマクロをヘッダ内で行っても良いことになっています。
この場合、ヘッダをインクルードすればマクロが、ヘッダなしで呼び出せば外部定義の関数が呼び出されることになります。ヘッダをインクルードした場合でも、引数なしでabsだけを(すなわち関数へのポインタとして)使った場合は外部関数が使われますし、明示的に(abs)(123)のように関数名を括弧でくくれば、マクロではなく外部関数を呼び出すことができます。
No.2
- 回答日時:
★追記。
・objファイルはバイナリファイルですので、普通に開いても関数の内容は見れません。
でも関数をコンパイルして機械語(アセンブラ)レベルで関数の処理内容が分かります。
逆アセンブルなどすれば分かるかも。→その前に obj ファイルの構造を解読しないと
いけませんね。
・標準関数のソースが処理系に付属していれば見れます。
でも自分で実装してみるとよりC言語の仕組みを理解できます。→自分でも実装できる。
過去に『ライブラリのソースを見る方法はないでしょうか?』という質問がありました。
http://oshiete1.goo.ne.jp/qa2856744.html→『C言語のライブラリ』をどうぞ。
・下に printf 関数だけですが実装例を載せます。
#include <stdio.h>
#include <stdarg.h>
// 標準関数の printf 関数と等価です。
extern int printf( const char format[], ... )
{
char buff[ 1024 ];
va_list ap;
va_start( ap, format );
vsprintf( buff, format, ap );
va_end( ap );
return( fputs(buff,stdout) );
}
参考URL:http://libc.blog47.fc2.com/blog-category-8.html
No.1
- 回答日時:
★ちょっと違いますね。
・stdio.h、stdlib.h、string.h のヘッダファイルには、それぞれの関数のプロトタイプ宣言などが
記述されています。このプロトタイプ宣言がないとコンパイラさんに『そんな関数はないぞ』って
叱られます。
・strcpy 関数の場合は、ランタイムライブラリに関数の実体(内容)があります。
この関数を利用するには、使用する前にその関数のプロトタイプ宣言を記述する必要があります。
『extern char *strcpy( char *s1, const char *s2 );』という1行です。
この記述を行うとソースファイル以外の何処かに strcpy 関数の実体があるか、ライブラリにその
関数があるよ。ってコンパイラさんに教えてあげれます。するとソースファイルに strcpy 関数の
実体がなくてもライブラリや他のOBJファイルに strcpy が存在していればそれをリンカで結合して
くれます。
・そして、標準なC関数はすべてライブラリに存在し提供されています。
これらの関数を使うには、必ずプロトタイプ宣言を記述しますが、毎回たくさんの同じ宣言を記述
するのは大変です。そこで、ヘッダファイルに処理を分類ごとに分けて記述してあります。
このことからユーザさんは(あなたも私も)ヘッダファイルをインクルードするだけで記述したことに
なるのです。
・そもそも、プリプロセッサ命令のインクルード(#include)は、ソースファイルの位置に別のソース
ファイルを自動的に挿入する機能です。自作関数を集めたヘッダファイルをインクルードすると
インクルードされた位置に自作関数の実体を記述したのと同じ働きになります。
でも、標準にあるヘッダファイルには、関数の実体が記述されているわけではありません。注意!
・また、自作関数を集めたヘッダファイルはライブラリにして利用することをお勧めします。
そして、自作関数をライブラリにした場合もその関数群を使うにはプロトタイプ宣言が必要です。
そのプロトタイプ宣言を集めて記述したファイルこそ『ヘッダファイル』なのです。
・決して printf 関数などがヘッダファイルに実装されているわけではありません。宣言のみです。
・以上。分かりますか?こんな説明で。
なるほどなるほど!ありがとうございます。
私が今まで作っていたライブラリはライブラリではありませんでした・・。
ただ名前を.hにしただけのファイルでした^^;
objファイルってなんなんだ?と思っていましたが、インクルードするファイルの関数があるものなんですね??
・・ってことはobjファイルをひらけばそこに関数の内容を見ることが出来るんでしょうか?
しかしそうなるとprintfはどうやって書かれているんだ・・と思うのですが、各標準関数はどのように実装されているのかその中身を見る事はできますか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- Visual Basic(VBA) 該当セルに行替えを含むデータを命令文に入れて、2行に表示したい。 5 2023/07/20 11:51
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- Visual Basic(VBA) 集めたシートのシート名を変更したい。 下記のコードでサブフォルダにあるファイルのSheet3を集めて 6 2022/08/23 10:38
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語初心者の質問失礼します。
-
csvファイルを開かずに文字を検...
-
Thunderbirdでemlファイルを開...
-
ファイル名の先頭にアンダース...
-
バッチで118項目のCSVを処理し...
-
ドラッグアンドドロップでファ...
-
CSVファイルへの保存の際、デー...
-
SGファイルって何ですか?
-
大きいサイズのテキストファイ...
-
なぜjQuery UIを使う時こんな...
-
VBに、Cのincludeのようなもの...
-
分割コンパイルの#defineについて
-
ASP .NETでファイル選択ダイア...
-
グローバル変数のよくない使い...
-
VBAでHTMLファイルを扱うにはど...
-
ループ中にセルの更新された値...
-
マスタとファイルの違いって?
-
Cでのネットワークファイルの読...
-
同じ名前のファイルを作った場...
-
Javaソース上でのきれいなSQLの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語初心者の質問失礼します。
-
ファイル名の先頭にアンダース...
-
csvファイルを開かずに文字を検...
-
バッチで118項目のCSVを処理し...
-
CSVファイルへの保存の際、デー...
-
グローバル変数のよくない使い...
-
テキストファイルの最終行を削...
-
ドラッグアンドドロップでファ...
-
VB.NETによるプロセス間通信
-
VBAにてEXCEL以外のファイル(テ...
-
分割コンパイルの#defineについて
-
ファイルの結合
-
iniファイルに追記がしたいです。
-
VBに、Cのincludeのようなもの...
-
動画処理のライブラリについて
-
Cでのネットワークファイルの読...
-
ダイアログボックスで複数フォ...
-
C言語のfopenについて教えてく...
-
「VBScript」ADODB.Streamにお...
-
マウスポインタの変更
おすすめ情報