马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
java import和c include区别 AI答复
Java中的import关键字和C语言中的#include预处理处罚指令在功能和用途上有明显的区别。以下是它们之间的一些重要差别:
- 作用机制:
- Java import:import关键字用于从其他包或类中导入范例(如类、接口、罗列和表明),以便在当前文件中使用这些范例时不须要使用它们的完全限定名(包名和类名)。import语句只是指示编译器在编译时到那里查找这些范例,它并不会将导入的包或类的内容复制到当前文件中。因此,纵然导入了多个包或类,也不会增长编译后文件的巨细。
- C #include:#include预处理处罚指令用于将指定文件的内容插入到当前源文件中。这个被包罗的文件通常是一个头文件(.h),它包罗了函数声明、宏界说、范例界说等。预处理处罚器会在编译之前实行#include指令,将头文件的内容复制到当前源文件中。如果包罗了多个头文件,且这些头文件中有重复的内容,那么这些重复的内容会被多次复制到当前源文件中,从而大概导致编译后的文件变大。
- 编译时活动:
- Java import:Java编译器在编译时剖析import语句,并根据须要查找和加载相应的类文件(.class)。只有当实际使用到某个类时,编译器才会加载该类的字节码。这种加载方式称为动态加载或按需加载。
- C #include:#include指令在编译之前由预处理处罚器实行,它实际上是将头文件的内容复制到当前源文件中。因此,在编译时,编译器看到的是已经包罗了头文件内容的源文件。如果头文件中有语法错误或依靠关系题目,这些题目会在编译时被发现。
- 语法和使用:
- Java import:import语句的语法是import PackageName.ClassName;大概import PackageName.*;(导入整个包)。使用import可以进步代码的可读性,淘汰定名辩说,并在肯定程度上进步性能(由于编译器可以在编译时验证范例)。
- C #include:#include指令的语法是#include <header_file>(用于包罗标准库头文件)或#include "header_file"(用于包罗用户自界说的头文件)。使用双引号时,编译器会先在当前源文件地点目次下查找头文件,如果找不到再到体系标准库目次下查找。
- 依靠关系处理处罚:
- Java:Java通过包和类来管理依靠关系,并使用类加载器在运行时加载类。这提供了更机动的依靠管理和动态加载本领。
- C:C语言通过头文件来管理依靠关系,但这种方式相对静态,且轻易导致循环依靠题目。C语言没有内建的依靠管理工具,通常依靠开发者手动管理头文件包罗次序和依靠关系。
综上所述,Java的import和C的#include在作用机制、编译时活动、语法和使用以及依靠关系处理处罚等方面都存在明显的差别。这些差别反映了Java和C语言在操持哲学、编译模子和依靠管理方式上的差别。
java编译示例
demo3源码- package demo3;
- import demo4.Demo4;
- /**
- * @author yaoct
- * @date 2023/12/21 16:17
- * @description:
- */
- public class Demo3 {
- public static String method3(){
- System.out.println("demo3");
- return "mothod3";
- }
- public static void main(String[] args) {
- Demo4.method4();
- }
- }
复制代码 demo4源码- package demo4;
- import demo3.Demo3;
- /**
- * @author yaoct
- * @date 2025/2/24 13:49
- * @description:
- */
- public class Demo4 {
- public static void method4(){
- System.out.println("demo4"+ Demo3.method3());
- }
- }
复制代码 demo5源码- package demo5;
- /**
- * @author yaoct
- * @date 2025/2/24 14:24
- * @description:
- */
- public class Demo5 {
- public static void method5(){
- int v=1;
- }
- }
复制代码 目次结构
可知demo4.Demo3.java与demo4.Demo4.java相互依靠,(以下省略包名)
如果只编译Demo3.java- javac -d out demo3\Demo3.java
复制代码 同时天生Demo3.class和Demo4.class
固然初始不存在Demo4.class,由于Demo3.java依靠Demo4.java,会在编译Demo3.java时,同时编译Demo4.java。可知javac下令编译支持源码循环依靠。而Demo5.java未自制。
可以使用以下下令编译多个包下的源码- javac demo3\Demo3.java demo4\Demo4.java demo5\Demo5.java
复制代码 运行时如果依靠的class文件不在当前工作目次,须要添加classpath路径
如果将demo4.Demo4.class移动到E盘,实行需以下下令,此中多个类路径用;风格- java -cp .;E:\ demo3.Demo3
复制代码 c语言编译示例
123.c源码- #include "demo1.h"
- #include <stdio.h>
- #include <stdlib.h>
- int accum1 = 1;
- int accum2;
- extern int accum3;
- int sum1(int x, int y)
- {
- int t = x + y + accum1 + accum3;
- return t;
- }
- int main(int argc,char *agrv[])
- {
- printf("value:%d",sum2(1,2));
- return 1;
- }
- int sum2(int x, int y)
- {
- return sum1(x,y)+method1(333);
- }
- void fun1()
- {
- int n = 10;
- int *arr = (int*)malloc(n * sizeof(int)); // 分配一个可以存储10个整数的数组
- if (arr == NULL) {
- printf("Memory allocation failed\n");
- }
- // 使用arr...
- free(arr); // 使用完毕后释放内存
- }
复制代码 demo1.h源码demo111.c源码- #include "demo1.h"
- int method1(int x)
- {
- return x;
- }
复制代码 由于c语言的预处理处罚须要将#include指令包罗的文件 全量导入。全部须要
- 使用前向声明:在头文件中只声明(而不界说)函数或变量,将界说放在源文件中。如许,纵然头文件被多次包罗,也不会导致重复界说的题目。
- 使用头文件掩护:在每个头文件的开头使用预处理处罚指令(如#ifndef, #define, #endif)来防止头文件被多次包罗。
gcc工具包罗了编译器、汇编器、链接器等一系列工具,以下是通过下令单步实行。
预处理处罚
得到123.i的预处理处罚文件
这个文件内容较多,这里不展示,除了包罗123.c源码之外,还包罗了库函数stdio.h,stdlib.h与demo1.h的头文件
在实行编译指令天生汇编语言
编译
得到汇编代码- .file "123.c"
- .globl accum1
- .data
- .align 4
- .type accum1, @object
- .size accum1, 4
- accum1:
- .long 1
- .comm accum2,4,4
- .text
- .globl sum1
- .type sum1, @function
- sum1:
- .LFB2:
- .cfi_startproc
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset 6, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register 6
- movl %edi, -20(%rbp)
- movl %esi, -24(%rbp)
- movl -24(%rbp), %eax
- movl -20(%rbp), %edx
- addl %eax, %edx
- movl accum1(%rip), %eax
- addl %eax, %edx
- movl accum3(%rip), %eax
- addl %edx, %eax
- movl %eax, -4(%rbp)
- movl -4(%rbp), %eax
- popq %rbp
- .cfi_def_cfa 7, 8
- ret
- .cfi_endproc
- .LFE2:
- .size sum1, .-sum1
- .section .rodata
- .LC0:
- .string "value:%d"
- .text
- .globl main
- .type main, @function
- main:
- .LFB3:
- .cfi_startproc
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset 6, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register 6
- subq $16, %rsp
- movl %edi, -4(%rbp)
- movq %rsi, -16(%rbp)
- movl $2, %esi
- movl $1, %edi
- movl $0, %eax
- call sum2
- movl %eax, %esi
- movl $.LC0, %edi
- movl $0, %eax
- call printf
- movl $1, %eax
- leave
- .cfi_def_cfa 7, 8
- ret
- .cfi_endproc
- .LFE3:
- .size main, .-main
- .globl sum2
- .type sum2, @function
- sum2:
- .LFB4:
- .cfi_startproc
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset 6, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register 6
- pushq %rbx
- subq $24, %rsp
- .cfi_offset 3, -24
- movl %edi, -20(%rbp)
- movl %esi, -24(%rbp)
- movl -24(%rbp), %edx
- movl -20(%rbp), %eax
- movl %edx, %esi
- movl %eax, %edi
- call sum1
- movl %eax, %ebx
- movl $333, %edi
- call method1
- addl %ebx, %eax
- addq $24, %rsp
- popq %rbx
- popq %rbp
- .cfi_def_cfa 7, 8
- ret
- .cfi_endproc
- .LFE4:
- .size sum2, .-sum2
- .section .rodata
- .LC1:
- .string "Memory allocation failed"
- .text
- .globl fun1
- .type fun1, @function
- fun1:
- .LFB5:
- .cfi_startproc
- pushq %rbp
- .cfi_def_cfa_offset 16
- .cfi_offset 6, -16
- movq %rsp, %rbp
- .cfi_def_cfa_register 6
- subq $16, %rsp
- movl $10, -4(%rbp)
- movl -4(%rbp), %eax
- cltq
- salq $2, %rax
- movq %rax, %rdi
- call malloc
- movq %rax, -16(%rbp)
- cmpq $0, -16(%rbp)
- jne .L8
- movl $.LC1, %edi
- call puts
- .L8:
- movq -16(%rbp), %rax
- movq %rax, %rdi
- call free
- leave
- .cfi_def_cfa 7, 8
- ret
- .cfi_endproc
- .LFE5:
- .size fun1, .-fun1
- .ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)"
- .section .note.GNU-stack,"",@progbits
复制代码 可知汇编代码123.s中并不包罗前面预编译文件123.i的头文件的界说,只包罗函数名调用信息,阐明123.i中头文件中的界说的作用只是用于该步调的编译。
汇编
再实行指令天生可重定向文件123.o静态链接
重复实行前面步调编译demo111.c文件天生demo111.o可重定向文件,再实行指令天生可实行文件a.out |