他の人が指摘したように、ヘッダー foo.h は、ソースファイル foo.c によって提供される機能を使用できるようにするために必要な情報を宣言する必要があります。これには、foo.c によって提供される型、列挙、および関数が含まれます。(グローバル変数を使用しませんよね? 使用する場合は、それらも foo.h で宣言されます。)
ヘッダー foo.h は自己完結型で冪等でなければなりません。自己完結型とは、すべてのユーザーが foo.h をインクルードでき、他のどのヘッダーが必要になるかを心配する必要がないことを意味します (foo.h にはそれらのヘッダーが含まれているため)。冪等性とは、ヘッダーが複数回含まれている場合、損傷がないことを意味します。これは、古典的な手法によって実現されます。
#ifndef FOO_H_INCLUDED
#define FOO_H_INCLUDED
...rest of the contents of foo.h...
#endif /* FOO_H_INCLUDED */
質問は次のとおりです。
ファイル foo.c には、foo.c のすべての宣言を含む foo.h が含まれています。bar.c と bar.h も同様です。foo.c 内の関数 foo1() は、bar.h で宣言され、bar.c で定義されている bar1() を呼び出します。ここで問題は、bar.h を foo.h 内または foo.c 内に含める必要があるかどうかです。
foo.h が提供するサービスが bar.h に依存しているかどうかによって異なります。foo.h を使用する他のファイルが、foo.h の機能を使用するために、bar.h によって定義されたタイプまたは列挙のいずれかを必要とする場合、foo.h は、bar.h が (それを含めることによって) 含まれていることを確認する必要があります。ただし、bar.h のサービスが foo.c でのみ使用され、foo.h を使用するユーザーには必要ない場合は、foo.h に bar.h を含めないでください。