01:引言-[程序设计语言]-摘记&注解

阅读导航

本系列其他文章目录请戳这里

1.机器语言>汇编语言>高级语言

语言是人与人的一种交流工具,就比如我现在用汉语来写这篇博文来交流探讨技术问题;程序设计语言也是如此,只是交流对象不是人而是机器。

我可以用汉语来写博文,也可以用英语来写(假如我英语熟练);我可以用PHP来写一个网站,也可以用ASP.NET来写。

这就说明语言的本质就是一种交流工具,而我选择哪种语言来交流并不会影响我要的结果。然而在实际中到底要选用那个语言确要根据具体情况而定,这是个成本问题,比如我如果今天脑子抽筋要用日语,那我写着也累(关键是也不会)、读者或许也会骂娘了。

早期的计算机是一台超级庞然大物,能耗抵得上一家小型工厂,而计算能力确不如今天的一台手持计算器。也就是当时人力成本要远远低于这台机器的机器成本,也就决定了当时是以机器为中心,而不是人。所以人们用计算机能直接理解的机器语言来编写程序。

这里有一个计算两个整数的最大公约数的栗子(MIPS R4000处理器的机器语言),16进制形式如下:

1 2dbdffd0 afbf0014 oc1002a8 00000000 0c1002a8 afa2001c 8fa4001c
2 00401825 10820008 0064082a 10200003 00000000 10000002 00832023
3 00641823 1483fffa 0064082a 0c1002b2 00000000 8fbf0014 27bd0020
4 03e00008 00001025

这些机器语言对人的阅读和理解相当的不友好。当程序越来越复杂,人们迫切需要一种简单不易出错的记法形式,于是人们创造了汇编语言,用简短的词语来助记机器操作。

用MIPS R4000处理器的汇编语言重写上面的栗子如下:

 1    addiu  sp,sp-32
 2    sw     ra,20(sp)
 3    jal    getint
 4    nop
 5    jal    getint
 6    sw     v0,28(sp)
 7    lw     a0,28(sp)
 8    move   v1,v0
 9    beq    a0,v0,D
10    slt    at,v1,a0
11 A: beq    at,zero,B
12    nop
13    b      C
14    subu   a0,a0,v1
15 B: subu   v1,v1,a0
16 C: bne    a0,v1,A
17    slt    at,v1,a0
18 D: jal    putint
19    nop
20    lw     ra,20(sp)
21    addiu  sp,sp,32
22    jr     ra
23    move   v0,zer

对于这个栗子,阅读和理解上明显要比机器语言要容易得多。然而这种编码形式计算机是不识别的,需要一种叫做“汇编器”的程序来翻译成对应的机器的机器语言才能执行。

这种一个汇编指令对应一个机器之路的关系还是显而易见的,对于不同的计算机,则还需不同的汇编语言来编写;这个时代的程序设计仍然是以机器为中心,程序员也许要以机器的思维来解决问题。

就如同机器语言到汇编语言的过渡一样,程序越来越复杂、各种类型的计算机越来越多,为每一种机器都编写程序也越来越困难、人力成本也越来越大。

根据计算机科学领域惯用的抽象原则,人们需要一个中间层来隔离某一个计算操作对具体机器的具体操作指令的这种对应关系,也就是这个中间层需要独立于具体的机器操作。随后人们就创造出了高级程序设计语言来做这么一个中间层,由于剥离了计算操作到具体机器操作的对应关系,但是机器具体执行的依然还是机器操作,那么也就需要一个更“高级的翻译器”来做这项翻译工作,这个高级的翻译器就是现在所说的编译器。

由于这种翻译工作是由机器来完成的,在编译器出现的早期时候,人们总是能够写出比高级语言代码更高效的相应的汇编语言(毕竟早期的时候计算机的计算能力还一种奢侈的资源)。但是随着程序进一步的扩大、硬件性能的提升、编译器的优化、程序的维护成本等等变化,这种性能差异和人力成本相比慢慢也就显得微不足道了。

现在想一想,当初c++面世的时候、基于虚拟机技术的java出现时也是这么一种情况。

自从高级程序设计语言出现以后,程序设计慢慢开始从以机器为中心向以人为中心转变。

2.编译和解释

按照抽象的观点来看,高级语言的编译和执行大致是如下的样子:

编译器把源程序翻译成目标程序(典型的是机器语言程序)后就隐退了,后面的程序的运行中就不在需要编译器的存在了。

解释器是另外一种实现高级语言的方式:

和编译器不同的是,解释器一直全程守候。解释器本身相当于一个“虚拟机”,它的“机器语言”就是源程序的高级语言。

和编译器相比,解释器可以有更大的灵活性。它可以轻易地做到在程序运行初期来生成某一块新的代码,然后再后续的某一个时间去执行它;以及把一些决策推迟到运行时再去做决定。和解释器相对应,编译型的语言通常可以带来较好的性能,它可以在编译时期就把一些决策确定下来,比如一些内存布局。

虽然两者的概念很清晰,也有较大的差异性,然而现实中有些语言是“混合型”的,流程大致如下:

如果初期阶段的翻译器比较简单,则我们把它称为解释型语言;如果翻译阶段复杂,则成为编译型语言。

然而简单和复杂本身是个形容词,而不能可量化。完全有可能出现一个复杂的翻译器负责中间语言程序的生成,一个复杂的虚拟机(解释器)来执行中间语言,JAVA、.NET也正是这种实现方式。

  • 连接器和预处理器

我们所用的高级语言所写的程序通常还需要一个库(包含一些IO、网络等等的操作),在编译的时候就需要把我们写的源程序和库程序链接到一起来生成目标代码,比如我要读写文件,则需要链接IO相关的库程序。通常情况下目标代码为汇编语言而不是机器语言,这种方式更有利于调试程序,也便于阅读,更能把编译器和机器语言文件格式的变化隔离开来。

预处理器可以提供一种条件编译的功能,比如C#中编译条件#if DEBUG这些东西,再如C、C++中的宏机制也是属于预编译的范涛。

3.程序语言的设计实现以及分类

现实中语言的设计和实现总是有不可调和的矛盾,从设计角度来看总是希望一个语言能有更强大的表达能力,然而却总是受到语言的实现制约。这根本原因大概也许是以人为中心和以机器为中心的矛盾吧,因为你的语言的执行最终还是离不开机器的执行,所以语言设计者也是不得不在这两者中间寻求平衡。

依据现有的计算模型(运算产生结果或运算影响结果),大致分为两大类(当然这些所谓的分类也是从不同角度得来的,如果你站在另外的角度看,或许就是另外一番景象了)说明式语言和命令式语言。从某种的角度看,说明式语言明显要更“高级”,因为它更贴近使用者-程序员,而更远离实现者-语言设计者。然而现在的语言还是命令式占据着统治地位,主要是因为实现的难度、性能的要求等原因制约着说明式语言的发展。上层是抽象的高级语言,下层是实现的细节,抽象层级越高,实现的难度则越大,因为你要隔离隐藏的细节越复杂。

函数式语言是说明式语言中的一个,近年它的热度也是急剧上升来着;我们熟知的C、C++、JAVA,C#等都是属于冯诺依曼体系的范涛,当然也是命令式语言的子集。和函数式语言中的把函数和数值作为语言的一等公民(可以赋值为给变量、作为参数传递、作为返回值处理)不一样的是,冯诺依曼语言的中的基本操作是赋值语句,它们通过“副作用”去影响后续的计算结果。

脚本语言比如JS,它们一般都是拥有强大灵活度的解释性语言,一般充当着“粘结剂”的角色。

等等还有诸多的语言分类,就不在此赘述了。

后话

由于这些都是我个人理解的一家之言,难免会有一些不当之处,欢迎园友们来交流探讨。

01:引言-[程序设计语言]-摘记&注解

时间: 2024-10-24 14:34:46

01:引言-[程序设计语言]-摘记&注解的相关文章

[程序设计语言]-摘记&注解-目录

这篇博文干嘛的 前一周写了一篇博文“记-码农的“启蒙”之<程序设计语言-实践之路>和<面向对象分析和设计>两书”,其中说打算总结下这两本书中有哪些收获,这个系列文章呢,就是关于第一本书<程序设计语言-实践之路>的. 这本书能带来什么 首先这是一本介绍语言的入门书籍(笔者阅读是裘宗燕老先生翻译的第二版),如果你想从中学到一些独门绝技,那么抱歉,木有. 其次它介绍的是程序设计语言的一些重要基础概念.各种概念之间的关系:并解释了语言中诸多结构的形成和发展过程,以及他们演化到今

02:名字、作用域和约束(Bindings)-[程序设计语言]-摘记&amp;注解

阅读导航 本系列其他文章目录请戳这里. 1.名字.约束时间(Binding Time) 2.对象生存期和存储管理 2.1静态分配 2.2基于栈的分配 2.2堆分配和垃圾收集 3.作用域规则 3.1静态作用域 3.2嵌套子程序 3.3动态作用域 4.引用环境的约束 4.1子程序闭包 4.2一级和二级子程序 5.作用域里的约束 1.名字.约束时间(Binding Time) 在本篇博文开始前先介绍两个约定:第一个是“对象”,除非在介绍面向对象语言时,本系列中出现的对象均是指任何可以有名字的东西,比如

[程序设计语言-摘记&amp;注解]-03:控制流

阅读导航 本系列其他文章目录请戳这里. 0.概述 1.表达式求值 1.1赋值(1)-引用和值 1.1赋值(2)-装箱和拆箱 1.1赋值(3)-多路赋值 1.2表达式里的顺序问题&数学的等值关系 1.3短路求值 2.结构化和非结构化的流程 2.1goto的机构化替代品 2.2继续(Continuations) 3.顺序复合(Sequencing) 4.选择 4.1短路条件 4.2case/switch语句 5.迭代 5.1枚举控制器的循环 5.2迭代器 5.3逻辑控制的循环 6.递归 6.1迭代和

清风注解-Swift程序设计语言:Point11~15

目录索引 清风注解-Swift程序设计语言 Point 11. 数值型字面量 代码事例: let decimalInteger = 17 // 十进制的17 let binaryInteger = 0b10001 // 二进制的17 let octalInteger = 0o21 // 八进制的17 let hexadecimalInteger = 0x11 // 十六进制的17 注解: 整数字面量可以被写作:十进制数,没有前缀:二进制数,前缀是 0b:八进制数,前缀是 0o:十六进制数,前缀是

清风注解-Swift程序设计语言:Point1~5

目录索引 清风注解-Swift程序设计语言 Point 1. Swift风格的"Hello, world" 代码事例: println("Hello, world")  注解: Swift语言的编码风格类似于C或Objective-C.因此,拥有C或Objective-C开发经验的人更容易掌握Swift语言. 在Swift中,没有包含在任何类或函数当中的代码,属于拥有全局作用域的代码. 你不需要为了输入输出或者字符串处理导入一个单独的库. println函数是Swi

清风注解-Swift程序设计语言

前言 Apple发布了全新的Swift程序设计语言,用来开发iOS和OS X平台的应用程序.其目的不言而喻:就是为了给老迈的Objective-C一个合适接班人!因此,不难预见,未来10年必然是Swift语言大放光彩的时代.“长江后浪推前浪,前浪死在沙滩上”-作为一名程序员,紧跟时代潮流是必须具备的职业素养.学习和运用Swift是每一个Apple开发者都必将经历的一个过程. <清风注解>这个系列的诞生目的有三:一是为了鞭策自己,二是为了与大家一起学习Swift,三是分享学习过程中的苦与乐.我会

《C程序设计语言(第2版&#183;新版)》第0章 引言

从这篇开始,按照我的理解,整理Kernigham和Ritchie的<C程序设计语言(第2版·新版)>. 0.1 C C很适合用来编写编译器和操作系统,被称作“系统编程语言”:BCPL语言-->B语言-->C语言: 数据类型:基本(字符,多种长度整型和浮点型):派生(指针,数组,结构,联合):表达式:运算符+操作数,总可以作为语句:指针:提供与具体机器无关的地址算术运算: 控制流结构:语句组,条件判断(if-else),多路选择(switch),终止测试在顶部的循环(while, f

程序设计语言学习

人,程序,计算机 计算机的诞生就是为了帮助人们完成一些任务.计算机以其速度快.失误少.持续时间长.保存时间久等特点弥补了人类的不足. 程序是计算机完成人类任务的计划书.说明书.指导书或者说是执行步骤. 运行程序就是计算机照着计划书执行任务的过程. 程序设计语言则是人们写计划书的语言.与人们给自己写计划书用汉语.英语等语言一样,人们给计算机写计划书要用计算机能够认识的语言——机器语言,也就是01串.这也是可编程计算机刚刚出现时人们使用的语言. 但是01这种二进制的语言不好记忆.不好交流.不好理解,

awk程序设计语言之-awk基础

awk程序设计语言之-awk基础 1 http://man.linuxde.net/ 2 7 8 常用工具命令之awk命令 9 awk是一种编程语言,用于在Linux/Unix下对文本和数据处理.数据可以来自标准输入(stdin).一个或多个文件,或其他命令的输出.它支持用户自定义函数和动态正则表达式 10 等先进功能,是Linux/unix下的一个强大编程工具.它在命令行中使用,但更多是作为脚本来使用,awk有很多内建功能,比如数组.函数等,这是它和c语言的相同之处,灵活性 11 是awk最大