在各个源⽂件中,作为不同的模块来组织。这时编译各个⽂件时就会⽣成⽬标⽂件(Object file)⽽不是前⾯说的可执⾏⽂件。⼀般⼀个源⽂件的编译都会对应⼀个⽬标⽂件。这些⽬标⽂件⾥的内容基本上已经是可执⾏代码了,但由于只是整个项⽬的⼀部分,所以我们还不能直接运⾏。待所有的源⽂件的编译都⼤功告成,我们就可以最后把这些半成品的⽬标⽂件“打包”成⼀个可执⾏⽂件了,这个⼯作由另⼀个程序负责完成,由于此过程好像是把包含可执⾏代码的⽬标⽂件连接装配起来,所以⼜称为链接(Link),⽽负责链接的程序就叫……就叫链接程序(Linker)。链接程序除了链接⽬标⽂件外,可能还有各种资源,像图标⽂件啊、声⾳⽂件啊什么的,还要负责去除⽬标⽂件之间的冗余重复代码,等等,所以……也是挺累的。链接完成之后,⼀般就可以得到我们想要的可执⾏⽂件了。
但既然编译型与解释型各有优缺点⼜相互对⽴,所以⼀批新兴的语⾔都有把两者折衷起来的趋势,例如Java语⾔虽然⽐较接近解释型语⾔的特征,但在执⾏之前已经预先进⾏⼀次预编译,⽣成的代码是介于机器码和Java源代码之间的中介代码,运⾏的时候则由JVM(Java的虚拟机平台,可视为解释器)解释执⾏。它既保留了源代码的⾼抽象、可移植的特点,⼜已经完成了对源代码的⼤部分预编译⼯作,所以执⾏起来⽐“纯解释型”程序要快许多。
编译型:⼀次把所有的代码转换成机器语⾔,然后写成可执⾏⽂件;
解释型:在程序运⾏的前⼀刻,还只有源程序⽽没有可执⾏程序;⽽程序每执⾏到源程序的某⼀条指
令,则会有⼀个称之为解释程序的外壳程序将源代码转换成⼆进制代码以供执⾏,总⾔之,就是不断地解释、执⾏、解释、执⾏……所以,解释型程序是离不开解释程序的。
编译型与解释型,两者各有利弊。前者由于程序执⾏速度快,同等条件下对系统要求较低,因此像开发操作系统、⼤型应⽤程序、数据库系统等时都采⽤它,像C/C++、Pascal/Object Pascal(Delphi)、VB等基本都可视为编译语⾔,⽽⼀些⽹页脚本、服务器脚本及辅助开发接⼝这样的对速度要求不⾼、对不同系统平台间的兼容性有⼀定要求的程序则通常使⽤解释性语⾔,如Java、JavaScript、VBScript、Perl、Python等等。
但既然编译型与解释型各有优缺点⼜相互对⽴,所以⼀批新兴的语⾔都有把两者折衷起来的趋势,例如Java语⾔虽然⽐较接近解释型语⾔的特征,但在执⾏之前已经预先进⾏⼀次预编译,⽣成的代码是介于机器码和Java源代码之间的中介代码,运⾏的时候则由JVM(Java的虚拟机平台,可视为解释器)解释执⾏。它既保留了源代码的⾼抽象、可移植的特点,⼜已经完成了对源代码的⼤部分预编译⼯作,所以执⾏起来⽐“纯解释型”程序要快许多。
动态语⾔和静态语⾔
通常我们所说的动态语⾔、静态语⾔是指动态类型语⾔和静态类型语⾔。
(1)动态类型语⾔:动态类型语⾔是指在运⾏期间才去做数据类型检查的语⾔,也就是说,在⽤动态类型的语⾔编程时,永远也不⽤给任何变量指定数据类型,该语⾔会在你第⼀次赋值给变量时,在内部将数据类型记录下来。Python和Ruby就是⼀种典型的动态类型语⾔,其他的各种脚本语⾔如VBScript也多少属于动态类型语⾔。
python和vb的代码可以通用吗(2)静态类型语⾔:静态类型语⾔与动态类型语⾔刚好相反,它的数据类型是在编译其间检查的,也就是说在写程序时要声明所有变量的数据类型,C/C++是静态类型语⾔的典型代表,其他的静态类型语⾔还有C#、JAVA等。
对于动态语⾔与静态语⾔的区分,套⽤⼀句流⾏的话就是:Static typing when possible, dynamictyping when needed。
强类型定义语⾔和弱类型定义语⾔
(1)强类型定义语⾔:强制数据类型定义的语⾔。也就是说,⼀旦⼀个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。举个例⼦:如果你定义了⼀个整型变量a,那么程序根本不可能将a当作字符串类型处理。强类型定义语⾔是类型安全的语⾔。
(2)弱类型定义语⾔:数据类型可以被忽略的语⾔。它与强类型定义语⾔相反, ⼀个变量可以赋不同数据类型的值。
强类型定义语⾔在速度上可能略逊⾊于弱类型定义语⾔,但是强类型定义语⾔带来的严谨性能够有效的避免许多错误。另外,“这门语⾔是不是动态语⾔”与“这门语⾔是否类型安全”之间是完全没有联系的!
例如:Python是动态语⾔,是强类型定义语⾔(类型安全的语⾔); VBScript是动态语⾔,是弱类型定义语⾔(类型不安全的语⾔);JAVA是静态语⾔,是强类型定义语⾔(类型安全的语⾔)。
静态类型定义语⾔
⼀种在编译时,数据类型是固定的语⾔。⼤多数静态类型定义语⾔强制这⼀点,它要求你在使⽤所有变量之前要声明它们的数据类型。Java 和C是静态类型定义语⾔。
动态类型定义语⾔
⼀种在执⾏期间才去发现数据类型的语⾔,与静态类型定义相反。VBScript和Python是动态类型定义的,因为它们是在第⼀次给⼀个变量赋值的时候出它的类型的。
强类型定义语⾔
⼀种总是强制类型定义的语⾔。Java和Python是强制类型定义的。如果你有⼀个整数,如果不显⽰地进⾏转换,你不能将其视为⼀个字符串。
弱类型定义语⾔
⼀种类型可以被忽略的语⾔,与强类型定义相反。VBScript是弱类型定义的。在VBScript中,可以将字符串‘12’和整数3进⾏连接得到字符串‘123’,然后可以把它看成整数123,⽽不需要显⽰转换。但其实它们的类型没有改变,VB只是在判断出⼀个表达式含有不同类型的变量之后,⾃动在这些变量前加了⼀个clong()或(int)()这样的转换函数⽽已。能做到这⼀点其实是归功于VB的编译器的智能化⽽已,这并⾮是VB语⾔本⾝的长处或短处。
结论:
静态是类型编译时判断;动态是类型运⾏时判断;强类型是类型独⽴,不轻易转化;弱类型是类型不严格区分,⼀般是只要⼤⼩放得下,就可以转化。这种是汇编级的观点。⾯向对象的观点并⾮这样的,对象并不是⼤⼩差不多就是类型兼容,⽽是关键的接⼝要相同才叫类型兼容。
动态语⾔并⾮是弱类型,这是不等价的。恰好的,⼀般动态语⾔都是强类型语⾔,因为都是遵照⾯向对象的观点来设计对象的。
动态语⾔的劣势很明显,就是缺少开发环境,运⾏效率差,当然语⾔设计上也不完美(静态语⾔何⽌千万,但c++也就⼀个)。
优势也很明显,就是编写容易,层次⾼,接近⾃然语义。动态类型语⾔效率低下的原因,不在于变量的类型是动态的,⽽在于对象的⽅法是动态联编的,在这⼀点上动态类型语⾔和Java没什么不同。
静态类型语⾔的优势究竟是什么?
观点⼀:静态类型语⾔因为类型强制声明,所以IDE可以做到很好的代码感知能⼒,因为有IDE的撑腰,所以开发⼤型系统,复杂系统⽐较有保障。
对于像Java来说,IDEA/Eclipse确实在代码感知能⼒上⾯已经⾮常强了,这⽆疑能够增加对⼤型系统复杂系统的掌控能⼒。但是除了Java拥有这么强的IDE武器之外,似乎其他语⾔从来没有这么强的IDE。C#的VisualStudio在GUI开发⽅⾯和Wizard⽅⾯很强,但是代码感知能⼒上和Eclipse差的不是⼀点半点。⾄于VisualC++根本就是⼀个编译器⽽已,羞于提及Visual这个字眼。更不要说那么多C/C++开发⼈员都是操起vi吭哧吭哧写了⼏⼗万⾏代码呢。特别是像LinuxKernel这种⼏百万⾏代码,也就是⽤vi写出来的阿,够复杂,够⼤型,够长⽣命周期的吧。
观点⼆:静态语⾔相对⽐较封闭的特点,使得第三⽅开发包对代码的侵害性可以降到很低。动态语⾔在这点上表现的就⽐较差,我想⼤家都有过从⽹上下载某个JS包,然后放到项⽬代码⾥发⽣冲突的经历
也就是说静态类型语⾔可以保障package的命名空间分割,从⽽避免命名冲突,代码的良好隔离性。但是这个观点也缺乏说服⼒。
静态类型语⾔中C,VB都缺乏良好的命名空间分割,容易产⽣冲突,但是并没有影响他们做出来的系统就不够⼤,不够复杂。
⽽Visual C++开发的DLL版本冲突也是臭名昭著的,似乎C++的命名空间没有给它带来很⼤的帮助。
⽽动态类型语⾔中Ruby/Python/Perl都有⽐较好的命名空间,特别是Python和Perl,例如CPAN上⾯的第三⽅库成吨成吨的,也从来没有听说什么冲突的问题。
诚然像PHP,JavaScript这样缺乏命名空间的动态语⾔很容易出现问题,但是这似乎是因为他们缺乏OO机制导致的,⽽不是因为他们动态类型导致的吧?
说到⼤型系统,复杂业务逻辑系统,Google公司很多东西都是⽤python开发的,这也证明了动态类型语⾔并⾮不能做⼤型的复杂的系统。其实我个⼈认为:
动态类型语⾔,特别是⾼级动态类型语⾔,反⽽能够让⼈们不需要分⼼去考虑程序编程问题,⽽集中精⼒思考业务逻辑实现,即思考过程即实现过程,⽤DSL描述问题的过程就是编程的过程,这⽅⾯像UnixShell,ruby,SQL,甚⾄PHP都是相应领域当之⽆愧的DSL语⾔。⽽显然静态类型语⾔基本都不
满⾜这个要求。
那静态类型语⾔的优势究竟是什么呢?我认为就是执⾏效率⾮常⾼。所以但凡需要关注执⾏性能的地⽅就得⽤静态类型语⾔。其他⽅⾯似乎没有什
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论