5

ばかげた質問であることは認めます。コードはそれをよりよく説明します。これらのファイルを取得しました:

こんにちはC:

#include <stdio.h>

void hello(char * s)
{
    printf("hello, %s\n", s);
}

main.c:

int main()
{
    hello("world!");
    return 0;
}

メイクファイル:

test : main.o hello.o
    gcc -o test main.o hello.o

main.o : main.c
    gcc -c main.c

hello.o : hello.c
    gcc -c hello.c

.PHONY : clean
clean :
    -rm test
    -rm main.o
    -rm hello.o

「make」して「./test」するだけで動作します。コンパイラが関数プロトタイプを認識できるように、main.c に hello.h のようなものを含める必要があるのではないでしょうか?

どこにも hello.c を含めていませんでした。なぜ main.c は hello 関数を知っているのでしょうか?

それが機能する場合、いつ .h ファイルが必要になりますか? 私は C プログラミングの初心者ですが、この概念は理解しやすいと思っていましたが、今では完全に混乱しています。

4

2 に答える 2

13

フラグを使用すると (常に-Wallフラグと共に使用する必要があります)、次のメッセージが表示されます。-Werror -Wextra

main.c: In function 'main':
main.c:3: warning: implicit declaration of function 'hello'

そして、コンパイラは何をすべきかを効果的に「推測」しますが、これは多くの状況で災害につながる可能性があります。

ヘッダー ファイルを正しく使用すると、この種の警告を回避できます。

于 2013-01-14T01:41:24.880 に答える
5

ヘッダーファイルは必要ありません。代わりに、関数にはプロトタイプが必要です。helloパスを呼び出すと"world"、Cは、をとって1つの引数の関数を呼び出していることを認識し、char*すべてを正しく実行します。ただし、これは機能しません。ただし、関数がfloatを取得し、それをassにすることにした場合 int(試してみてください。非常に有益です)。下位互換性の理由から、Cではプロトタイプなしで関数を呼び出すことができますが、危険です。たとえば、の呼び出しの場合hello、コンパイラは、を返す関数を呼び出していると見なしますint。技術的には、未定義の動作を呼び出しているため、プログラムが誤って動作します。

ヘッダーは、プロトタイプを提供するための最も便利な方法を提供しますが、次のようにコード自体で提供できます。

void hello(char*);

int main()
{
    hello("world!");
    return 0;
}
于 2013-01-14T01:43:57.420 に答える