脚本宝典收集整理的这篇文章主要介绍了c语言的#include和java的import的区别以及库调用,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
#include是个宏命令,在文件编译阶段,会先将#include展开,也就是说被#include引用的文件会在源文件中展开。
举例:
有两个.c源文件,一个是my.c还有一个是main.c
假如my.c文件内容是:
void fun(int x){PRintf("%dn",x);}
而main.c文件的内容是:
#include"my.c" int main() { return 0; }
那么编译之前的预处理步骤,就会把#include的内容在main.c中展开,则变成:
void fun(int x){printf("%dn",x);} int main() { return 0; }
当然,一般来讲是#include .h文件,而不是.c文件。
然后编译器实际上是对新的内容进行编译处理。
编译的步骤则是:编译步骤
而java的import是否也是将代码展开呢?
答案是否定的。
java语言中,每一个类都必须要用包名.类名的形式来描述。
只给出类名是无法完全描述一个类的,比如我们要用HashMap这个类就需要写成这样:
java.util.HashMap map = new java.util.HashMap();
这样的话每个类的调用都要这么麻烦,要记住包名,这样很不利于写项目代码。
java作为一门先进的现代编程语言,它的开发者也想到了这个问题,于是使用import来指定包或者直接指定类的
名字,这样就不需要每次都将类完全描述,使得开发者能够专注于软件开发而不是各种包的导入。
有了import之后,代码就变成了这样:
import java.util.*; ... HashMap map = new HashMap(); ...
不像c中的#include直接展开,这样做实际上只是指定了要引用的类,而具体的被引用类的代码则在执行的时候才调入内存(这个步骤是类加载器来实现的)。
这样做的好处是编译(编译成.class文件)速度较快,运行速度稍慢,而c语言的展开方式编译会非常慢,运行则很快。
当然c语言中也有运行时将代码调入内存的技术,即动态连接技术。
不过c语言的动态连接实在是麻烦,就好像是在现代社会中我要获得火种,非得钻木取火。
而且动态连接的前提还得是有动态链接库才行,如果没有就得自己写一个,写完之后编译的命令(编译成库文件和编译成可执行文件的命令)还不不一样。
有了库之后,就可以调用了,但是调用库又变成了一个无法理解的事情。
比如调用windows下的dll动态链接库中的函数:
#include <windows.h> #include <stdio.h> typedef int (*Fun)(int,int); int main() { HINSTANCE hDll; Fun Add; hDll=LoadLibrary("myDll.dll"); if (hDll==NULL) { printf("%s","failed to load dll!n"); } else { printf("%s","succeeded in loading dlln"); Add=(Fun)GetProcAddress(hDll,"add"); if (Add!=NULL) { printf("%dn",Add(12,94)); } } FreeLibrary(hDll); return 0;}
在这个动态库调用中,明明已经知道有个函数add(int,int),还非得写一堆东西,上面的那个typedef是定义了一个函数指针,为了指向add这个函数,但是???what???开发人员调用库的目的就是为了简单,就是为了方便,就是为了好用,如果调库还需要这么麻烦,还需要定义什么指针,那还调库干嘛。
而java的动态连接则不存在这种问题,因为java的设计原则中只有库,class文件就是库,而.jar不过是一堆的.class文件。在java编程中引用一个类实际上就进行了一次动态连接,并且这种动态连接却和调用本类一样方便,就比如自己写了一个my.MyMap类,在别的类里直接new my.MyMap()就可以了,完全没有上面的那些步骤。
当然能这么方便是得益于虚拟机中的类加载器。
以上是脚本宝典为你收集整理的c语言的#include和java的import的区别以及库调用全部内容,希望文章能够帮你解决c语言的#include和java的import的区别以及库调用所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。