0

重複の可能性:
ヘッダーのない C プログラム

私は長い間 C を勉強してきました。しかし、私を悩ませていることの 1 つは、今日 C プログラムを作成し、stdio.h および conio.h ヘッダー ファイルをインクルードするのを忘れて、ファイルを kc.c として保存したことです。この .c ファイルをコンパイルして実行すると、期待どおりの出力が得られました。

しかし、標準ヘッダー ファイルを使用せずに C プログラムを実行するにはどうすればよいでしょうか。

または、私が聞き逃している概念に気づいていませんか?

編集:プログラム

int main()
{
  int i=12,j=34;
  int *pa=&i,*pb=&j;
  printf("the value of i and j is %d %d respectively ",*pa,*pb);
  getch();
  return 0;
}

ここで STDIO.H ヘッダーの printf() 関数を使用したため、それを含めずに、どのようにコンパイルして正常に実行できますか?

4

3 に答える 3

5

コンパイラは物事を機能させることができますが、そうする義務はありません。

すべての可変引数リスト関数は、使用する前に宣言する必要があります。適切に宣言しprintf()ないと、未定義の動作が発生します (有効な未定義の動作の 1 つは、期待どおりに動作することです)。

C99 モードでコンパイルすると、宣言されていない関数に関する警告が表示されるはずです (ただし、Turbo C にはおそらく C99 モードがありません)。


ニットピッキング:

[H]標準ヘッダー ファイルを使用せずに C プログラムを実行するにはどうすればよいですか?

すべてのプログラムは、ヘッダーをまったく使用せずに実行されます。ただし、ほとんどのプログラムは標準ヘッダーを使用して標準関数を宣言するようにコンパイルされており、より優れたプログラムでは、すべての関数が使用前に宣言されている (または使用前に静的関数として定義されている) ことが保証されます。

C99 ではこれが必要ですが、多くのコンパイラでは誤ったプログラムのコンパイルが許可されます。ただし、コンパイルは診断を生成する必要があります。診断によってコンパイルが失敗する場合とそうでない場合があります。実際には、通常はコンパイルが失敗することはありませんが、コンパイルが失敗する可能性があり、一部のコンパイラ (GCC など) では、コンパイラの操作を強制できます (GCC の-Werror=missing-prototypes -Werror=old-style-definitionオプションなど)。

于 2012-09-09T06:12:27.253 に答える
2

適用される言語標準が ISO C99 よりも前の場合、C では、関数を参照する前に関数を宣言または定義する必要はありません。

ただし、コンパイラがそのような関数呼び出しに遭遇すると、関数が int を返し、不定の数と型のパラメーターを受け取ると単純に想定します。これを暗黙の宣言と呼びます。後で関数を宣言するか、異なる数のパラメーターまたは互換性のないパラメーターで関数を呼び出すと、一部のコンパイラーで、2 番目の呼び出しが最初の呼び出しで暗黙的に示された宣言と一致しないという警告が表示される場合がありますが、ISO C89 標準では関数を次のように扱います。 variadic [printf() のような] 任意の数と型のパラメーターが許可されます。

さらに、実際の戻り値が int でない場合、受け入れられて処理された戻り値は、何らかの形で意味をなさない可能性があります。

暗黙の宣言に依存するのは悪い形式であり、ほとんどのコンパイラは警告を発行します。コンパイラがそうしなかった場合は、警告レベルを上げる必要があります。これらの診断は、コードの品質を向上させるのに役立ちます。単に警告を無視した場合 (その問題に関する警告) は、すべきではありません。

C++ では規則が厳しく、関数のオーバーロードを許可する必要があるため、関数を参照する前に関数を宣言または定義しないとエラーになります。

于 2012-09-09T06:15:29.330 に答える
1

ヘッダー ファイルは、定数、プリプロセッサ マクロ、および関数プロトタイプのリストにすぎません。関数プロトタイプは、各関数が取る引数を C に伝えます。

コンパイラは、対応するプロトタイプまたは関数定義なしで使用されている関数を検出すると、形式の暗黙的な宣言int func()を生成します。C 関数は (C++ の場合のように) 関数シグネチャではなく名前だけでリンクされるため、リンカーは後で標準ライブラリ内の関数定義を見つけます。

于 2012-09-09T06:13:49.953 に答える