我最近问过this question有关在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
#################################################################
答案 0 :(得分:2)
您已经获得了有关使用GCC和Makefile的反馈,并且已经注意到完成任务的典型方法是两个.c文件和一个.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.
在我的示例中,函数声明位于调用它的模块中,似乎符合A-B-C示例。 (令人困惑的部分是全局范围注释,但我不会说函数声明的范围是全局的。例如,如果你将声明移到main()下面,它就会让事情变得混乱。我还没有发现一些东西。尽管如此,对这一点具有严格的权威性。)
答案 1 :(得分: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方法适用于模块。 c 。
如果根据你的任务,你不能使用标题或全局声明,你可以在函数内声明原型:
void somefunc () {
char *whatever (int x); // prototype
printf("%s\n", whatever(12));
}
很好,假定whatever()
在某处定义,在编译和运行它时会起作用。
答案 2 :(得分: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;
按照我的说法,不要像我一样!