问下两个程序的关系
我是不是可以理解为hello.c里面包括了test.c所以say()函数可以直接调用,又因为test.c里面没有包括hello.c,因此要将printline()定义为外部函数。那么,如果在test.c里面Include<hello.c>是否可以直接调用?
我是不是可以理解为hello.c里面包括了test.c所以say()函数可以直接调用,又因为test.c里面没有包括hello.c,因此要将printline()定义为外部函数。那么,如果在test.c里面Include<hello.c>是否可以直接调用?
2015-11-17
因为文件hello.c的printLine()函数和test.c中的say()函数是被相互引用的,因此这两个函数都应为外部函数,在两个文件中都必须声明引用。所以小编的答案是错误的!具体代码如下:
hello.c文件中:
#include <stdio.h>
#include "test.c" //引用test.c文件
extern void say();
void printLine() //这里定义的方法对吗?
{
printf("**************\n");
}
int main()
{
say();
return 0;
}
test.c文件中:
#include <stdio.h>
extern void printLine();
void say(){
printLine();
printf("I love imooc\n");
printf("good good study!\n");
printf("day day up!\n");
printLine();
}
这里面的错误可不只是在hello.c的第三行,写这代码的人似乎没搞明白什么是头文件...
首先你要明白:include是个预处理指示,代码在编译前会将被include的文件内容写入进来。
所以实际上say函数也是定义在hello.c中的,那么问题来了:在say中调用了printLine,但前面没有printLine函数的声明! 这是不应该的。不过因为C有隐式声明的特性,所以编译器不会在这里报错,它会为printLine自动推导出一个函数声明。
可下面的代码就是 static void printLine() 这个函数定义!这与前面编译器自动推导出的函数声明冲突了! 而且static属性与自动推导的非static声明严重冲突,编译器会就此报错!
再后面的main就别看了...
这题目的意思似乎是让你把第三行的static去掉(或是换成extern),这样确实能编译通过。但仍然存printLine函数声明冲突的问题!最终仍能编译通过是因为编译器忽略了自动推导的版本而接受了代码中的版本(在两个版本都是非static的情况下)。 但你要明白,这没有解决原本的问题!问题的根源出在:say函数前没有printLine的声明!
其实这样的代码是误用了“include头文件”的功能。
正确的做法是:被include的文件都应该是所谓的“头文件”,也就是只含有声明的文件。 test.c中是say函数的定义,不应直接包含到hello.c中。 应该将say函数的声明写到另一个test.h中,再在hello.c中include <test.h>
另外头文件中还必须要做“重复包含保护”,显然被include的test.c中也没有这样做。
你明白“编译”“链接”等概念的话,会更能理解为什么要这样做。
那么本课用这样的代码作示例是非常不恰当的! 要么是讲师也不懂,要么就是想把学生搞得更糊涂......
举报