python和java和c语⾔的区别-Python与C语⾔有什么区别?答题练⼿。⼿机排版不佳请谅解~
更新2:还是关于编译和解释
⼆者的本质区别是在编译/解释器的总体⼯作⽅式上的,编译器是off-line,解释器是on-line。编译器把整个程序读进来,进⾏⼀系列变⼤变⼩转化优化的过程,产⽣可执⾏⽂件,然后编译器退出,由可执⾏⽂件来读取和输出数据。解释器就像启动了⼀个打印机,不把纸和数据送进来它就⼀直闲置开着。解释器启动后相当于⼀个online服务,⼀有程序和数据进来就会经历类似编译的过程并直接产⽣结果,从这个意义上更接近于直接执⾏。
⼀种语⾔可能既可以编译,也可以解释,但⼀般来说可以解释的语⾔都可以编译。通常所说编译型语⾔和解释型语⾔应该是指它最常见的解析⽅式。
更新:关于编译型和解释型
解释型并⾮可以直接运⾏。所谓直接运⾏是使⽤REPL(Read-Eval-Print Loop,即读代码-求值-打印结果循环)或者虚拟机⼀键运⾏(如python <⽂件名>)带给你的假象。实际上GNU调试器GDB也可以实时执⾏C代码,但不能因此说C是解释型语⾔;Google的编译型语⾔Dart也可以直接dart <⽂件名>运⾏,然⽽⼈家要有main函数⼀次编译整个⼯程。
实际上python main.py这个命令会启动python虚拟机和解释器,将main.py的代码⼀⾏⼀⾏解释,只不过不同于REPL,它不会把每⼀⾏表达式的值打印出来。解释的过程也需要词法、语法分析和向⽬标代码(python字节码)的转化,也就是每⼀⾏都需要⼀个完整的编译过程(实际情况可能没这么简单)。类定义和函数定义会检查语法,但未定义的标识符不会报错,所以定义顺序不影响引⽤。python虚拟机实际执⾏的是编译完的字节码,⽽不是源代码。
对⽐C和Java,每次必须先编译(gcc, javac)再执⾏(./main, java Main),看上去⽐python更不"直接”,但区别真的不⼤。C之所以⼀经编译就⽆法跨平台,是因为他要编译到⽬标机器和操作系统的可执⾏⽂件。然⽽同样需要整个⼯程编译的Java,只拥有编译后的⽂件,就可以在装了兼容的JRE的各种平台运⾏。
不过,还真有可以直接运⾏的解释型语⾔。详情请查"Lisp Machine”。
原回答若有与此更新冲突的地⽅,以此更新为准。
=== 以下是原答案 ===
1. C 属编译型语⾔,Python 属解释型语⾔。
这点其他答主提过,确实是重要的区分点。编译型和解释型,在编程时的最⼤区别是必不必要写⼀个
⼊⼝函数,在C语⾔⾥是 `main`,⽽Python 可以不写。
编译型的优点是"静态”,代码不能⼀⾏⼀⾏编译执⾏,必须作为整个⼯程来编译,这样便于类型检查,降低运⾏时错误率;运⾏时效率更⾼,因为编译器可以统筹各个⽅⾯,⽣成更优化的机器指令;⼀经编译便可直接以机器语⾔再次执⾏。
解释型语⾔的优点是"动态”,代码的每⼀⾏可独⽴执⾏(代码块除外)。这样就可以灵活地进⾏实时交互,调整正在运⾏的程序,进⾏实时、异步的调试。⽐如 Python 的 CLI(命令⾏交互界⾯)就可以直接输⼊ Python 代码执⾏。这是 C 语⾔这样的编译语⾔难以做到的(调试模式下可以做到 C 表达式的实时计算,但达不到解释型语⾔的灵活度)。解释型语⾔的特性还让其适合做脚本语⾔。⽽且有⼀个东西是不⽀持解释的语⾔做不到的,就是eval,即将编译时未知的字符串转化为在原位置的代码执⾏。由于编译型语⾔在运⾏时⽆法编译代码,所以实现不了eval。 />
⼆者的缺点则互为对⽅占优的⽅⾯。编译型需要⼤量的编译时间,不够灵活。在⼤项⽬中,需求的更改可能导致巨⼤的重新编译时间。不过这被运⾏效率弥补,没有其他更⼤的缺点。⽽解释型语⾔被诟病得相对较多,⽐如因为不能事先编译,执⾏时都要先解释(本质上就是对单⾏的编译)成机器代码再执⾏,因此效率低很多。不过针对这点,Python 现在会像编译型语⾔⼀样把第⼀次执⾏时产⽣的字节码(虚拟机器代码)输出到 .pyc ⽂件,下次若源⽂件未改变,可直接执⾏字节码⽂件,从⽽提升了
运⾏效率。另外,解释型语⾔难以实现静态类型检查,所以容易产⽣运⾏时错误,因此相对不适合⽤来做⼤项⽬。
其实⾮要让编译型语⾔也能⽀持命令⾏交互也并⾮不可能——Haskell就是这样⼀个例⼦。它不仅能单⾏执⾏,甚⾄还能做静态类型检查,这个会在后⾯提到。做到这⼀点必须精⼼设计语⾔。
2. C 是弱类型、静态类型检查的,Python 是强类型、动态类型检查的。
对于不了解的⼈来说,这种说法可能会引起质疑。来⼀条⼀条看。C 是弱类型?各种「类型不匹配」快要把我搞疯了,这还弱吗?"静态类型检查”⼜是什么⿁?
理解这件事情,要先知道 C 语⾔中类型的本质:⼀定长度的字节。C 中⼤多数基本类型都是某种长度的整数:int, short, long, long long, char,各种 unsigned,甚⾄指针也只是地址——机器字长度的整数⽽已,唯独 float 与 double 特殊。稍复杂点的,有数组和结构体,它们只是若⼲个整数或浮点数的组合。这种简单粗暴是因为 C 出⽣很早,那时冯诺依曼体系的⾼级语⾔⼤都与汇编很接近——汇编⾥没有类型,只有不同长度的字节。⽽ Python 中你是看不到 int, unsigned int, long 的区分的,因为它把不同长度的整数类型简化了,超出长度就⾃动扩展。
扯远了。知道 C 中的类型⼤体就是各种整数,就能想到各种整数可以互相转化:int 转化 long 很好理
解,char 和 int 也经常互相转换,那你想过 int 能与任何⼀种指针强制转换吗?⽽这是源于 int 是最常⽤的整数类型,⽽地址也是最重要的机器整数。你还知道 void* 能与任何指针类型转换吗?其实所有的指针都可以任意互相转换,这意味着看似类型系统严格的 C 实际上并没有限制你去滥⽤它。这也不⼀定是滥⽤——库函数 malloc 的返回类型就是 void*,它表⽰你可以将它看作任何类型的指针。
那不同指针能相互转化⼜怎样呢?我们知道 Python ⾥的对象是⼀系列属性和⽅法的集合,这在 C 中类似于结构体。对象的名字相当于指向它在内存中实体的指针——相当于结构体指针。不同结构体指针可以任意转化意味着……内存中的对象可以被视为拥有任何类型,这不就是弱类型嘛!
那什么叫静态类型检查呢?对,就是那个让你饱受编译错误苦恼的东西。我说过编译型语⾔是"静态”的,所以静态类型检查只可能在编译型语⾔实现(前述,Haskell 是个杂糅者,它是编译型语⾔,但⼜可以单⾏执⾏)。C 要求你写出每个变量、函数的类型,就是为了类型检查。但并不是静态类型检查就⼀定要标注类型(如 Haskell 就⼏乎完全可以不写,得益于其类型推断系统,细写⼜是⼀篇论⽂)。Python "动态类型”,我可以理解,因为写的时候完全不⽤声明类型嘛。但你说它「强类型」?这我可不服了,哪个「强类型」语⾔可以随意给变量赋任意值的?
python转java代码前⾯说过,储存对象的变量实际上只是储存对象在内存中的地址(⽽「值类型」,如⼩整数,⼀般直接存储值)。变量存储在「栈」中,对象被放在「堆」中。「栈」是⼀个个整齐叠放的,「堆」是随
机开辟的。当我们执⾏ `a = [1,2,3]` 这样⼀条语句,Python 运⾏环境在「堆」中⽣成新的 list 对象,将对象的⾸地址返回,赋给新变量 `a` 压⼊栈中。之后若执⾏ `a = { 'x': 1 }`,只不过是将 `a` 中的地址换成字典对象的罢了。所以变量能储存任意对象不是因为变量本⾝能随意改变,⽽是指针可以指向任何东西。
⽽同样是指针能指向任何东西,Python 为何是强类型?因为 Python 的对象都携带了类型信息。如果你对整数和字符串做加法,它就会报这样的错误: />
这表明 Python 会对运⾏时的对象进⾏类型检查。这个其实还不够说明问题,因为加号不能⽤于 int 和 str 可能只是⼀种语义检查。那你可以想,当调⽤⼀个对象上不存在的⽅法会怎样,显然是会报错的。⽽更能说明问题的是这个: />
这表明 Python 的类型检查甚⾄⽐ C 更强,连 float 都不会给你隐式转化为 int。⽽这肯定不会是编译器⾏为,因为内置函数 chr 在声明时是不会标注参数类型的。尽管 3.7 版本允许类型声明,但 Python 不会以此为依据进⾏报错。另外,真正的弱类型语⾔ JavaScript 对上述整数加字符串、获取不存在的⽅法(调⽤会报错但获取不会)、整数参数传浮点数都不会报错。由此,你可以相信 Python 属于强类型语⾔了吧。
(补充:更彻底的弱类型语⾔⽐如 Lisp,甚⾄是在机器上实现弱类型的)
3. Python 是原⽣⽀持⾯向对象范式的语⾔,C 不是。
我没有说"Python 是⾯向对象语⾔,C 是⾯向过程语⾔”,因为⾯向对象和⾯向过程是编程模型和思想,Python 程序也能写得很"过程”,C 也有多种⽅法实现"⾯向对象”。但 Python 是原⽣⽀持⾯向对象范式的,它有 class 的封装,有继承、多态⽅法。C 要实现⾯向对象的特性,需要⼀些技巧。有⼀个知乎回答,我从它的第⼀个链接的 PDF 得到了很⼤启发。回答已经不到了,但那个 PDF 还存着,书名叫《Object-Oriented ANSI-C》。
以上三点是两个语⾔最⼤的区别。其他还有很多,不过都不涉及编程范式的核⼼。包括但不限于:C 更偏向底层,抽象和语法糖更少,使⽤起来不如 Python ⽅便。但 C 更简单,如果有计算机体系的知识,精通起来⽐ Python 可能更容易。
Python⽀持lexical scope、闭包、嵌套函数和嵌套类,C没有闭包。
C 的语法不如 Python 简洁。
C 函数声明的先后顺序影响其可被调⽤的区域,Python 不会。
C 需要⾃⼰维护堆内存,Python 有垃圾回收机制。
C 的跨平台性不如 Python(对于使⽤这两个语⾔的程序员⽽⾔),因为 C 是⼤多数操作系统的实现语⾔,各操作系统会提供标准之外的系统调⽤库,⽽不同操作系统上系统库中的函数和定义不同。Python 基于虚拟机执⾏字节码,只要官⽅提供了某操作系统的虚拟机实现,就能将 Python 代码⽆缝在各操作系统转移(`os.system` 等涉及特定操作系统的东西除外)。(其实这也不算⼀个区别,C和Python的跨平台性都靠各平台的语⾔服务,不过C主要是平台⾃⼰给Python主要是Python官⽅给。真要说能编译运⾏C/Python的平台数量C要多很多。)
C 除预编译指令外可以压缩到⼀⾏,Python 要⽤游标卡尺(逃。
……
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论