我有很多习惯使用Java作为编程语言,但我对C完全是新手。我理解头文件包含方法和变量的前向声明。这与Java中的抽象类有什么不同?
答案 0 :(得分:6)
答案简短:
抽象类是面向对象编程的概念。由于构造C语言的方式,头文件是必需的。它无法以任何方式进行比较
答案很长
要理解头文件以及头文件的需要,您必须理解“声明”和“定义”的概念。在C和C ++中,声明意味着您声明某些东西存在于某处,例如函数。
void Test(int i);
我们现在声明,在程序的某个地方,存在一个函数Test,它接受一个int参数。当您有定义时,您可以定义它是什么:
void Test(int i)
{
...
}
这里我们已经定义了函数void Test(int)实际上是什么。
使用extern关键字
声明全局变量extern int i;
它们的定义没有extern关键字
int i;
编译C程序时,将每个源文件(.c文件)编译为.obj文件。定义将作为实际代码编译到.obj文件中。编译完所有这些后,它们将链接到最终的可执行文件。因此,只应在一个.c文件中定义一个函数,否则,相同的函数将在可执行文件中多次结束。如果函数定义相同,这并不重要。如果将全局变量链接到同一可执行文件两次,则会出现问题。这将使一半代码使用一个实例,另一半代码使用另一个实例。
但是在一个.c文件中定义的函数无法查看另一个.c文件中定义的函数。因此,如果从file1.c文件中需要访问file2.c中定义的函数Test(int),则在编译file1.c时需要有一个Test(int)声明。当file1.c被编译成file1.obj时,生成的.obj文件将包含需要在某处定义Test(int)的信息。链接程序时,链接器将识别file2.obj包含file1.obj所依赖的函数。 如果没有包含此函数定义的.obj文件,您将收到链接器错误,而不是编译器错误(链接器错误更难以找到并纠正编译器错误,因为您没有获得结果的文件名和行号文件)
因此,您使用头文件存储相应源文件中存储的定义的声明。
答案 1 :(得分:4)
IMO主要是因为许多C程序员似乎认为Java程序员不知道如何编程“真实”,例如处理指针,内存等。
我宁愿将标头与Java接口进行比较,因为它们通常定义了必须如何使用API。
标头基本上只是一种避免复制粘贴的方法:预处理器在遇到#include
指令时只包含源文件中标头的内容。
您将每个用户通常使用的声明放入标题中。
答案 2 :(得分:3)
以下是答案:
Java在一些核心C程序员中声名狼借,主要是因为他们认为:
与Python等一些语言相比,Java现在几乎不是世界上最简单的语言。
它被用于许多桌面应用程序 - 经常不使用applet。最后,Java 总是比C慢,因为它不是直接编译到机器代码。但有时候,不需要极速。无论如何,JVM并不是有史以来最慢的语言VM。
当您在C中工作时,没有抽象类。
所有头文件都包含粘贴到其他文件中的代码。将它放在头文件中的主要原因是它位于文件的顶部 - 这样,您无需关心将函数放在实际实现文件中的位置。
虽然您可以在C中使用OO概念,但它没有内置的类和OO类似基础的支持。在普通的C中实现继承几乎是不可能的,因此实际上 实际上可能没有OO或抽象类。我建议坚持使用普通的struct
。
如果它让你更容易学习,那么一定要把它们想象成抽象类(实现文件是继承类) - 但恕我直言,这是一种难以理解的思维方式,用于在没有明确的语言的情况下工作支持所述功能。
我不确定Java是否有它们,但我认为更接近的类比可能是C#中的部分类。
答案 3 :(得分:2)
如果你转发声明的东西,你必须实际交付和实现它,否则编译器会抱怨。标题允许您显示“模块”的公共API,并使声明可用(对于类型检查等)到程序的其他部分。
答案 4 :(得分:2)
综合阅读:Learning C from Java。推荐阅读从Java到C的开发人员。
答案 5 :(得分:1)
我认为Java的嘲笑(嘲笑,嘲笑,蔑视,嘲笑)只是因为它很受欢迎。
抽象类和接口指定可以在特定类型的对象上调用的契约或一组函数。 C中的函数原型只能对函数参数/返回值进行编译时类型检查。
答案 6 :(得分:1)
虽然你的第一个问题对我来说似乎是主观的,但我会回答第二个问题:
头文件包含声明,然后预处理器通过#inclusion将这些声明提供给其他文件。 例如,您将在标题中声明一个函数,并将在.c文件中实现。其他文件将能够使用该函数,只要他们可以看到声明(通过包含头文件)。 在链接时,链接器将查找对象文件或链接的各种库,以查找为该函数提供代码的对象。
典型的模式是:您分发库的头文件,以及包含目标代码的dll(例如)。然后在您的应用程序中包含标题,编译器将能够编译,因为它将在标题中找到声明。无需提供代码的实际实现,通过dll可以为链接器提供。
答案 7 :(得分:1)
C程序直接运行,而Java程序在JVM内部运行,因此人们普遍认为Java程序运行缓慢。同样在Java中,您隐藏了一些低级构造(指针,直接内存访问),内存管理等...
在C中,函数的声明和定义是分开的。声明“声明”存在一个由这些参数调用的函数返回一些东西。定义“定义”函数实际执行的操作。前者在头文件中完成,后者在实际代码中完成。在编译代码时,必须使用头文件告诉编译器有这样的函数,并在包含函数二进制代码的二进制文件中链接。
在Java中,二进制代码本身也包含函数的声明,因此编译器查看类文件以获取可用函数的定义和声明就足够了。