1

ファイルがファイルを参照できるように、C で複数のファイルをコンパイルすることについて、最近この質問をしました。答えは、モジュールファイルをヘッダーファイルにして、それをメインインポートすることでした。main.cmodules.c

Cはモジュラーコンパイルをサポートしているため、これは間違った方法であると言われました。main.c私の Makefile は以下のとおりです。これはおそらく正しいと思われますが、 --の関数呼び出しごとにエラーが発生しますwarning: implicit declaration of function X

.c1 つのファイルではなく 2 つのファイル.cを使用して、これを正しくコンパイルするにはどうすればよい.hですか? main.cファイルには、 の関数main()を呼び出せるようにする必要がある関数が含まれていmodules.cます。

メイクファイル:

#################################################################
# Variables
# -- allows C-source and assembly-source files mix. Again, the
# -- indented lines start with a TAB(^I) and not spaces..
#################################################################

CFLAGS  = -g -Wall -Werror
LDFLAGS =
CC      = gcc
LD      = gcc

TARG    = driver
OBJS    = modules.o main.o

#################################################################
# Rules for make
#################################################################

$(TARG): $(OBJS)
        $(LD) $(LDFLAGS) $(OBJS) -o $(TARG)

%.o: %.c %.s
        $(CC) $(CFLAGS) -c $<

clean:
        rm -f *.o *˜ $(TARG)

print:
        pr -l60 Makefile modules.c main.c | lpr

#################################################################
# Dependencies -- none in this program
#################################################################
4

3 に答える 3

2

GCC と Makefile の使用に関するフィードバックを既に受け取っており、タスクを実行する一般的な方法は 2 つの .c ファイルと 1 つの .h ファイルであることが指摘されています。ただし、次の例で示すように、関数宣言を使用する場合は .h ファイルは必要ありません (これは間違いなく単純であり、保守性と有用性が劣ります)。

main.c:

void moduleFunc1(int); // extern keyword required for vars, not for functions

int main()
{
    moduleFunc1(100);

    return 0;
}

module.c:

#include <stdio.h>

void moduleFunc1(int value)
{
    printf("%d\n", value);
}

コンパイルする:

gcc main.c module.c

編集:あなたがリンクした割り当てを見た後、私の最善の推測は、実際には関数宣言があなたが探しているものであるということです。割り当てから引用するには、「その他」の下の #7:

A function should be declared in the module/function where
it is called and not in global scope. Say A calls B and C does
not call it then B should be declared in A only.

私の例では、関数宣言はそれが呼び出されたモジュール内にあり、ABC の例を満たしているようです。(紛らわしい部分はグローバルスコープのコメントですが、関数宣言のスコープがグローバルであるとは言いません。たとえば、宣言を main() の下に移動すると、混乱することに注意してください。何かが見つかりませんでしたただし、この点については厳密に権威があります。)

于 2013-09-15T18:09:29.623 に答える
0

課題を読んだ後、インストラクターは次のことを意味する可能性がありますか?

main.c:

#include <stdio.h>

int main() {
  int plus(int a, int b); /* declaration */

  printf("%d ", plus(4, 5));

  exit(0);
}

module.c:

int plus(int a, int b) {
  return a + b;
}

gcc -Wall -Wextra main.c module.c

ただし、 plus() はグローバル名前空間で使用できます。だから私は少し迷っています。

余談:

3. int next = 234;
   printf("%6d ", next);
   will print value of next, right justified in 6 columns

6. Use separate statements for declaration and initialization
   of a variable as:
   int xval;
   xval = 100;

私がするようにではなく、私が言うようにしてください!

于 2013-09-15T18:21:25.183 に答える
0

これはいくつかの方法で行うことができますが、どの方法を選択しても、main.c が module.c から関数を呼び出す場合、main.c は#includeそれらの関数のプロトタイプを宣言するヘッダーである必要があります。

最初の最も簡単な方法は、これを行うことです。

gcc -Wall -g main.c module.c -o myprogram

2 番目のより華やかな方法は、最初に module.c をオブジェクト ファイルとしてビルドすることです。この方法の主な目的は、複数の部分を含む大規模なプログラムを開発/デバッグ/コンパイルするときに時間を節約することです。全体を再コンパイルするのではなく、変更された部分を再コンパイルするだけです。また、パーツを簡単に組み合わせることができます。これは、makefile で行うのが最も簡単です。

myprogram: main.c module.o
    CC $(CFLAGS) main.c module.o -o myprogram

module.o:
    CC $(CFLAGS) -c module.c

makefile の「myprogram」ターゲットが (prereq) モジュールで動作することに注意してください。o一方、プレーンな gcc メソッドはモジュールで機能します。c .


割り当てに従って、ヘッダーまたはグローバル宣言を使用できない場合は、関数内でプロトタイプを宣言できます。

void somefunc () {
    char *whatever (int x);  // prototype
    printf("%s\n", whatever(12));
}  

whatever()問題ありません。どこかで定義されていると仮定すると、コンパイルして実行すると機能します。

于 2013-09-15T17:56:56.560 に答える