c语言的#include和java的import的区别以及库调用

#include是个宏命令,在文件编译阶段,会先将#include展开,也就是说被#include引用的文件会在源文件中展开。
举例:
有两个.c源文件,一个是my.c还有一个是main.c
假如my.c文件内容是:html

void fun(int x){printf("%d\n",x);}

而main.c文件的内容是:java

#include"my.c"
int main()
{
 return 0;
}

那么编译以前的预处理步骤,就会把#include的内容在main.c中展开,则变成:编程

void fun(int x){printf("%d\n",x);}
int main()
    {
     return 0;
    }

固然,通常来说是#include .h文件,而不是.c文件。
而后编译器其实是对新的内容进行编译处理。
编译的步骤则是:编译步骤windows

而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 dll\n");
        Add=(Fun)GetProcAddress(hDll,"add");
        if (Add!=NULL)
        {
            printf("%d\n",Add(12,94));
        }
    }
    FreeLibrary(hDll);
    
    return 0;}

在这个动态库调用中,明明已经知道有个函数add(int,int),还非得写一堆东西,上面的那个typedef是定义了一个函数指针,为了指向add这个函数,可是???what???开发人员调用库的目的就是为了简单,就是为了方便,就是为了好用,若是调库还须要这么麻烦,还须要定义什么指针,那还调库干吗。指针

而java的动态链接则不存在这种问题,由于java的设计原则中只有库,class文件就是库,而.jar不过是一堆的.class文件。在java编程中引用一个类实际上就进行了一次动态链接,而且这种动态链接却和调用本类同样方便,就好比本身写了一个my.MyMap类,在别的类里直接new my.MyMap()就能够了,彻底没有上面的那些步骤。
固然能这么方即是得益于虚拟机中的类加载器。code

相关文章
相关标签/搜索