1

我最近问了这个关于在 C 中编译多个文件以便一个文件main.c可以引用一个文件的问题modules.c。答案最终是将模块文件制作成头文件并主要导入它。

我现在被告知这是一种不正确的方法,因为 C 支持模块化编译。我的 Makefile 在下面,这应该是正确的,但是我在main.c--中的每个函数调用都收到错误warning: implicit declaration of function X

我需要做什么才能正确编译它,使用两个.c文件而不是一个.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 和 Makefiles 的反馈,并且注意到完成任务的典型方法是两个 .c 文件和一个 .h 文件。但是,如果您使用函数声明(可以说更简单,只是不太易于维护和有用),则不需要 .h 文件,如下面的示例所示。

主.c:

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

int main()
{
    moduleFunc1(100);

    return 0;
}

模块.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 从 module.c 调用函数,则 main.c 必须#include有一个为这些函数声明原型的标头。

第一种也是最简单的方法就是这样做:

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

第二种也是更华丽的方法是首先将 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 方法适用于模块。


如果根据您的分配,您不能使用标头或全局声明,您可以在函数内声明原型:

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

很好,并且假设whatever()在某处定义,当您编译和运行它时会起作用。

于 2013-09-15T17:56:56.560 回答
0

阅读作业后,您的老师可能是以下意思吗?

主.c:

#include <stdio.h>

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

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

  exit(0);
}

模块.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 回答