• 締切済み

printf() だけで文字列を表示できる??

1: int printf(char *, ...); 2: main() 3: { 4: printf("Hello, world.\n"); 5: } C で書かれた上のプログラムが正常にコンパイルでき、しかもHello, world. と表示することが理解できません。どなたか教えていただけないでしょうか。 1行目でprintf のプロトタイプ宣言を書き、その実体は書いていません。これをコンパイルしたとき、「printf() は知らない」と言われると思いましたが、そうはならず、Hello, world. を表示しました。 また、1行目の関数宣言の引数を変更すると、「ビルトイン関数と型が一致しない」と言われます。その「ビルトイン関数」というのは文字通りビルトインされていて任意に使用できるようになっているのでしょうか。 コンパイラはgcc version 3.4.4 です。

みんなの回答

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

<stdio.h>をインクルードしなくても、自分で関数原型を書けば問題ありません。 ただし、今回の場合は、その関数原型が正しくないようです。 printfは、 int printf(char *, ...); ではなく、 int printf(const char *, ...); としなければなりません。 ここが間違えているので、「ビルトイン関数と型が一致しない」といわれます。 GCCはコンパイラ自体がprintf関数の仕様を知っていますので、矛盾が指摘されているのです。 ただし、Cの場合はprintfという名前だけを頼りにリンクしていますので、シグニチャが間違っていてもリンクは通ってしまいます。 厳密にいえば、printfの定義と宣言の間で矛盾があるので未定義の動作ですが、実害はありません。 ただし、常にそうしたことが通用するとは限りません。 ある処理系では、constが付かないポインタはデフォルトで16ビット、constが付くポインタはデフォルトで32ビットになります。このような場合は当然破綻します。

すると、全ての回答が全文表示されます。
  • hitomura
  • ベストアンサー率48% (325/664)
回答No.2

> 1行目でprintf のプロトタイプ宣言を書き、その実体は書いていません。 > これをコンパイルしたとき、「printf() は知らない」と言われると思いましたが、 逆です。 プロトタイプ宣言を書いたことにより「こういう引数と戻り値のprintfという名前の関数があるよ」とコンパイラに教えることになります。その後のソース内で使用されているprintf()は引数指定がマッチしているため、コンパイル時にはエラーが発生しません。 次に問題が起きる可能性があるのはリンク時ですが、提示のコードではリンクしているライブラリファイル内のprintfの実体通りの引数指定を行っているため、リンクでエラーが発生することもありません。

すると、全ての回答が全文表示されます。
回答No.1

こんばんは。 > 1行目でprintf のプロトタイプ宣言を書き、その実体は書いていません。これをコンパイルした > とき、「printf() は知らない」と言われると思いましたが、そうはならず、Hello, world. を > 表示しました。 本来ならば、 #include <stdio.h> がいるはずで、ここに、printf のプロトタイプ宣言が書いてあります。 だから、stdio.h をインクルードすれば、1行目はいらない。 このソースでは、1行目のプロトタイプ宣言が #include <stdio.h> の代わりになっている。プロトタイプ宣言があるから、コンパイルはできる。 ソースコードに #include<stdio.h> があれば、リンカは明示的に libc(.so または .a) という printf の実体を含むライブラリをリンクするんですけど、gcc は デフォルトで libc をリンクするようなので、リンクもうまくいって、正しく動く。 > また、1行目の関数宣言の引数を変更すると、「ビルトイン関数と型が一致しない」と言われます。 > その「ビルトイン関数」というのは文字通りビルトインされていて任意に使用できるようになっている > のでしょうか。 libc をリンクするときに、libc に含まれる printf の実体の引数と、ソースコード上のプロトタイプ宣言が一致しないからこういわれます。なお、いま手元に gcc がないのでわかりませんが、gcc だと、printf のプロトタイプ宣言がなくても動くみたいですね。過去に似たような質問があったので、参照URLをどうぞ。      

参考URL:
http://okwave.jp/qa/q3686043.html
すると、全ての回答が全文表示されます。

関連するQ&A