什么是编程.pdf
Articles of 兮软兮软什么是编程什么是编程(工程工程,模式模式)2011-09-20 08:09:28 minlearn什么是平台,语言,及对应的编程既然是谈编程,自然有“编程到底难不难”,“学习编程到底应该怎么进行”诸如这样的话题的产生1,这些话题很自然地都会导到一个最基本的话题“什么是编程”,只有对编程有一个公共并格定一致的理解,我们才能进一步讨论那些稍微高级一点的话题而不必经常回到这个个人狭小的境地.什么是被解决了的问题?(被解决了的问题不应是成功个人的私人体会之类的见识而应是大家都承认并能理解的某种共识,比如“桌子是什么”,这样的问题才算是被解决了的问题).编程也可以成为这样的被解决了的问题,然而这需要很多铺垫。但是正如对对任何严肃问题的讨论都不能庞而统之一样,对于什么是编程,我们应从涉及到它的所有子概念开始讨论。TOC1 编程是一种人类工程1.1 PC系统工程1.2 程序与语言工程(映射工程)1.3 数据结构与算法工程1.4 应用建模工程1.5 为什么要用上面的方式解说什么是编程2 运行模型与语言模型,设计模型2.1 运行模式:为计算机引入一个编程层面,做进计算机2.2 语言模式2.3 语言模型用于实现平台模型3 编程语言3.1 平台与语言3.2 三种编程3.3 语言选择编程是一种人类工程编程是一种人类工程首先,什么是编程,从最直观的意义来说,编程是一种活动,当然这句话说了等于没说,然而这也正只是因为它没有继续把话说破,如果着眼于编程活动中出现的各大主体,那么编程实际上可以表述为:由人进行的,利用编程语言写系统逻辑或应用逻辑.针对计算机的,完成从方案域到应用域的一个变换的活动.这样的说法虽然也比较空白,但它至少提到了“计算机,人,应用,语言”,这就开始涉及了一些对编程的理解较为本质的东西.因为任何人类活动,它必定首先是个人类工程。只有从工程的眼光去看,那么,就抓住了总纲。一切活动都是人类的工程,编程作为人类工程,一般子多个人类子工程一步一步而来,这些子工程可以总结如下:PC系统工程;程序与语言语言工程;数据结构与算法工程系统;桌面编程基础建设工程;通用应用编程系统。以上实际上每个工程内部也存在着大量子工程,要实现这些工程,如果按照人的观点,那么从PC系统工程到通用应用编程系统是从难入易,反之如果按照机器的观点,则是由易入难。PC系统工程首先,对于PC系统工程来说,编程要通过计算机解决编程能解决的问题,它就必须(在功能层面)首先解决对于计算机系统本身的实现手段问题(硬件的实现和软件的OS);硬件方面,包括给PC提供一套数学理论模型支持(图灵理论),利用电子技术实现它(冯氏机器)。至于编程,最初的PC内部并没有一个天然集成的编程层面,它主要是作为裸机来运作的,指令来自外部,被输入进PC供执行。这种编程主要是面向硬件的汇编,比如硬件控制,或处理简单数值,文字的低级编程。软件方面,包括将PC本身(CPU和内存组成的存储体系)和越来越多的加入到PC体系中的硬件统一到一个更易于管理,更加强大的层面。并把以前PC仅能管理机器逻辑,简单数值,文字的能力扩展到能处理这些经过强化了的硬件逻辑的程度。这个层面就是软件层面。为什么需要出现一个软件系统呢?这是因为PC本身就是善于处理强大抽象的机器(数值,文字,机器逻辑,只是PC能表达的抽象的初级形态),它作为裸机使用的层面(裸机和汇编完成的简单任务)实际上是它功能的一小部分。于是,将硬件转为软件的第一步就是将硬件抽象为软件上可用的东西,更多的详情(实现一个OS),在对应的章节有详述。对应于裸机和汇编,软件系统实际上是平台加编程方式的全新升级,这样,PC就可以提供更多的功能(除了强化了的硬件逻辑,在这个基础上,还可以发展更多的抽象),接入更强大的编程方式 编程语言并运行这种语言产生的程序的支持。这样,PC就作为了同时整合了编程层面和平台层(软件层面是作为PC功能平台存在的层面,作为PC的一部分存在的)的机器。注:其实裸机下也有软件和软件系统的概念,比如软件包括写有0,1的纸带,代替人力管理机器的重启,暂停等汇编程序也是软件系统,但一般不承认它们是软件和软件系统,最初的软件系统一般指OS,软件一般指OS上运行的程序。但是,编程首先要通过计算机解决编程能解决的问题,它就必须在系统层面解决编程的结果 程序的表达和程序的运行问题,即编程和建造程序运行所在的平台,这二个问题实际上联系在一起的,PC系统(可能是硬件的,或软件的)要提供给程序一个执行路径对于程序的表达问题,编程要从根本上需要解决程序成不成立的事,这就是数学“可计算”,“可否形式化”问题的任务,这就是图灵理论解决停机问题的那一块。属于离散数学的内容。如果一个问题被证明为在有限步完成,它就被图灵理论所支持,能被形式化,适合被PC处理,等到以后,语言能用算法来映射现实生活的问题的形式化过程(这种过程称为离散化),所有这些都在以后有述。然后,PC要解决通过PC解决在软件层面运行程序的问题,即计算机系统(可能是硬件的,或软件的)要提供给程序一个执行路径.联系中的主体联系中的主体联系联系执行路径中的栈式2数据和代码静态数据栈式代码3子程序抽象运行体代码或数据暂且你不必明白以上图表表示的是什么意思,也不必理解软件的OS是如何运行编程结果-程序的运行问题的,这需要以后再说。程序与语言工程(映射工程)软件和软件编程的理想是好的,当软件平台搭建好的的时候(它能运行高级语言编成的程序),我们还需要提供一种映射手段,即程序与程序语言,这样方能实现一步一步实现最初的软件编程。然后是制造编译器完成映射的事;这就是说,现代的编程必然跟语言有关4,所以它必须首先解决语言的问题,它属于编程工程中的映射工程,它包括解决语言的内部实现问题(比如语法,语义)。以后会谈到语言的外部问题;这里你要着重看到语言这个字眼,通俗来说,这就是人们常常说的,编程就是学一门语言.这里的联系在于:联系中的主联系中的主体体联系联系语言与语法语义语言作为其内部实现的二大支撑概念,是用编译器理论来解决的;语言与人语言是由人来学的,要注意一个学习曲线问题语言与应用比如语言如何在语言内部实现的基础上表达并解决问题,以及形成一种做法标准,满足工业化快速开发的需要语言与人,语言与应用,参照下面“应用建模工程”节;数据结构与算法工程这一切导致了“软件编程”。以上解决了程序和编写程序的事情,还没有解决如何写程序的问题;这就是说,需要一种方式保证(可能是在理论层论证)这种开发方式是否可行的问题;编程要通过计算机解决编程能解决的问题,需要解决开发本身的问题,即理论层论证这种开发方式是否可行,比如统一使用数据结构和算法来解决功能开发上的问题,即编程首先是对于计算机的实现.而这个实现,在冯氏系统上(冯氏系统是一种本质上的数据处理系统),是通过一种数据化模式(先是以抽象类型的方式达到描述一种数据化的模式,再是数据结构)来进行的.这里你要着重看到冯氏系统,类型和数据结构这二个字眼.以及它们之间的联系,归纳如下:联系中的主体 联系 冯氏系统和类型 以抽象类型的方式达到描述一种数据化的模式(在编程层提供给冯氏系统更强大的编码能力)类型与数据结构 在抽象类型的基础上,用组织数据形成数据结构的方法来解决开发中的问题 冯氏系统和代码结构 在编程层提供给冯氏系统某种代码,让其操作处理经类型化的数据.所以对类型和代码的抽象,都是基于人的要求来的,同时编译器做了计算机与人之间的媒介应用建模工程上面说了,语言问题还包括它的外部,因为语言是由人来学的,所以对语言设计的考虑还包括着眼于它的外部,考虑其语法对于人的简单性和简单入阶性,语义映射到应用的那些能力;语言对于工业的统一性和强度性要求等.这就是说,编程是通过计算机来解决问题(这里侧重说的是问题)的,故它必须在语言的基础上抽象应用,解决对于应用端,问题端的抽象问题,比如对应用的设计问题.即设计模式.在一个大的范围里来说,应用问题本身是可以脱离语言被独立考虑的,但具体到用编程的方式来体现它,必然要涉及到如何用这种语言来体现上述应用与设计的问题.业界主要是用OO来解决这个问题的;经过大量争论,但经过OO多年的发展,它已经成了这个时代编程的基础,被沉淀作为基础知识5.比如语言能力中的class和设计中的OOAOOD,几乎是现代编程的代名词.这个时代不再是用不用的问题,而是一定要用的问题,这个问题早过时了,这些在语言之争中有述。对于编程者将编程机制接上现实概念的手段,比如,在用数据结构知识解决实现问题的时候,由于不够抽象,所以只能直接用内存的方法来抽象数据,那个时候是数据编程,这个手段在后来会越来越被抽象掉,甚至全然没有数据的概念,比如OO OO算起来还带有一点UDT到ADT的转变,而面向接口编程(它可以于OO来表现,即advanced oo 手段)将数据编程发展到了一个新的阶段等)这里你要着重看到设计模式和应用.这里的联系在于:联系中的主体 联系 问题与人 对于问题,编程如何解决人与它产生的设计关系 设计与语言 语言如何更好体现设计模式 对于软工问题,还有一个是处理大量人之间关系的学问,编程是大量人来进行的,所以它还必须解决它关于人6的要求的那些东西,即解决写法上的问题和对逻辑的表达方面的问题,设计上的问题和解决大规模开发的问题.即软工问题(它还包括分工等问题,软件过程问题),甚至调试问题(加入人对软件的后期干预因素)故软件调试不属于编程,而属于编程工程,现在的汇编承担着二种角色,即编程语言的角色(汇编编程或联合C混合编程),和作为编程工程中的调试工程的角色。这里你要着重看到人和设计.这里的联系在于:联系中的主体 联系 语言与对逻辑的表达 编译实现里面的类型对数据的产生模式 语言与写法 编译实现里面的,对写法的产生模式,对代码的组织模式 人和设计 综合考虑全部因素 最后编程,如果往深处说,它还应处理跟用户7有关的事,这个用户是产生软件需求的人,它不懂任何语言或库,你可以想象django中的template语言,这个用户使用无语法的声明性“代码”,这就将编程层次上升到了用户,将设计的任务从编程层次(我们说过,编程有运行层,语言层和设计层)中独立出来.即,对跟领域密切有关的设计的支持,可以不是语法编程要做的事,也可以不是程序员的事,它可以做到用户层和语法语言外面.比如,用一种类UML的接口语言转成语言的类体系(但是,迫切需要一种比OO还要高阶的语法语言,作为这种UML的目标,我们会在后面南辕北辙的UML加以详细讨论)所以说我们所指的编程绝非简单的二个字,而是由以上一切综合而成的一种人类活动,还以为“什么是编程”这个问题很简单吗?再加上这些问题都不是独立的而是联系着的,澄清它们是一个巨大的工程,为什么要用上面的方式解说什么是编程所以,如果说问题与问题之间总是关联着的,所以怎么样向他们去简单地说明白一件事呢?比如什么是编程。答案其实早就出来了,既然语言都面向综合解决编程中出现的这些问题,是个由人出发并终止于人的需求的系统活动,那么实际上对编程的概念的负责任的探索只能是一个无尽的过程,因为需要一切都综合而论,比如,谈对于一门编程语言的学习,一旦谈到了语言,即使在不谈到任何语言要素的情况下,选择什么样的语言这个小话题8实际上都会是一个巨大的问题,因为选择语言,它首先要解决如上我们谈到的几大问题,而只有弄清了这些,才能正确选好一门语言,而这只是编程的第一步,但问题是:初学者不可能对所有这些都有一个他们的理解,(我们这里谈到的编程是狭义的,即选择某种编程语言写系统逻辑或应用逻辑,而实际上还有广义的编程).也许我们只能从某些侧面和“形式”,“唯度”去说明.我们永远做不到把握事情真相的全部.即使有全世界那么多的纸张,“什么是人生”这样简单的问题我们也坚信写不完.但是对于人生,我们至少可以给出下面这样一些描述性的唯度,就像我们在本节的开头导出对于编程的那个描述性概念一样.”人生是一场由出生到死亡的存在”,”人生是一场梦想与财富的追逐”还比如,什么是计算机,这个问题其实跟什么是人生一样简单常见但是难解,但是我们可以站在计算机抽象组成的角度,给出一个足够简单的答案,计算机=硬件架构+软件OS,只要了解了硬件架构和软件OS,那么我们就可以说我们理解计算机了(当然,只是在某个唯度上而已,而且,具体到硬件架构和软件OS,又有巨大的唯度),让我们进入我们还没有完成的话题继续深入,什么是编程,在本章的开头已经给出了一个初步的概念,在那里,我们选择的抽象和唯度的组合是:程序被编程和被产生,被执行的主体与客体:即,编程的根本在于工程和抽象.本书即在站在这个大角度来讨论所有的大小唯度.要谈的工程 编程(整体上的编程是一种工程,以产出产品为目的)要谈的抽象 编程(具体的编程是一种抽象,以抽象概念和具化概念为手段)选取的唯度 程序被执行的宿主和编程语言,写程序的人和程序针对的应用 本书是以抽象为线,讲解平台,语言及基于平台语言的映射,即编程,这是本书的宗旨既然编程是一个工程,因此对任何编程问题的讨论都不可同日而论,故至少地,我们可以选择“平台与语言的关系”这个维度开始谈,因为任何开发实际上都是以先后顺序解决平台问题,语言问题和人的问题的过程,即,执行模型,语法模型,和设计模型的三段式过程.关于这个三个模型,后面还会有更深的讲解.于是,分清一切的首先是分清计算机,软件,与编程的区别。计算机科学的本质是由数学来完成的,它可分为硬件和软件系统,软件的本质是抽象,它可分为实现抽象(数结与算法)和组织抽象(对问题经抽象后形成的软件方案域),编程的本质是映射手段,映射和设计,更多地是一种艺术,这三者是相互渗透的,比如编程语言实际代表着几重角色的身份。运行时代表着它作为计算机系统和角色,语法代表着它能表达抽象和映射,用于设计的角色。但是正如系统跟语言不可分开写一样,应用和设计也不可能被分开讨论,其实这四个部分都是相互连接的不可分解的9,这又造成了讨论的复杂性。编程绝对不止是这样一个泛而论之的话题,因为在每个客体和主体的内部,又存在数量巨大的唯度和抽象,但我们可以照样根据找唯度的方法去理解它们.以下我们将极力从以上唯度中找到一些我们常见的词汇,以它们为根据,深入到这些词汇内部进行对编程的探讨.并附带讨论什么是最简单的语言,怎么样学习编程,为什么要这样学.于是我愿意只用上述列举出的表格和一些描述性的概念来表达它们.运行模型与语言模型运行模型与语言模型,设计模型设计模型模式其实指代一种对待问题的高层工程思想模型,对于上面在工程部分提到的五个工式程,在编程界存在三种模式,即,问题模式(比如数据结构和算法),设计模式(应该算是结合了问题和代码模式的综合模式了),代码模式(比如OO,高级语言机 制),这三者存在着巨大的联系,比如OO中的class是一种数据抽象而不是数据结构一样。还比如,过程式语法被证明可以构成任何图灵程序,其实也可能存在其它方案,也就是说,过程和函数只是万千可行方案中的一种。先来说说为什么说这三者其实是联系在一起的.运行模式:为计算机引入一个编程层面,做进计算机pc不但是作为应用平台存在的,而且是作为开发平台存在的,即它不但是应用机,而且是开发机,将编程集成进pc内部的编程最初的情况,远非我们今天看到的那样,而是经过了一步一步发展的才发展到我们能今天看到的样子的.其实只要拥有获取到程序的手段,计算机就可以执行这些程序完成它的事(这是计算机存在的唯一意义和必要条件,最初的解决手段是利用纸带编程,计算机内部并没有一个编程层面,这种模式是编程跟执行完全分离的模式),最初的计算机是不存在直接在计算机内部写程序的编程方式的.人们用0,1和纸带方式编程.编程层面处在运行层面之外.不过后来我们人类是通过编程来制造程序的而已,而且是在计算机内部进行的.这就为整个计算机在执行层面引入了一个编程层面,这样,计算机就引入了一个带执行和语言系统的编程层面了(即OS和高级语言)。不过,在能出现OS和高级语言的组合之前,还有一些更初始的应用平台和开发平台的组合.开发问题的解决过程实际上是同时解决平台问题和开发问题的综合过程.这二者是相辅相承的.只要存在一种平台,那么对其的开发支持就必不可少,任何平台上的任何开发都包括三个部分,平台层 也即运行层,解决平台实现的内核编程层,语言层,即编译层,和设计层,即对于人,程序员层)还记得我们在书一开始把人类自身比做“计算机”的话题吗?不妨接着想象一下,如果我们人也是电器化的东西,也有控制器等等,比如我们人可以是一个生物硬盘,那么当人们被接入计算机时,编程的工作,也就变成了用0,1组成代码,即,机器语言就是高级语言,编译原理这样的知识根本不用去学.因为用不着编译器和汇编器这样的转换用的东西.人机高度统一,而且思想一致,直接交流即行,这样的话,世界也许不是像现在这样.因为我们毕竟不是生物硬盘,我们具备不了机器分辨位而且能做到巨细无差的能力,而且我们也不能选择改造机器(我们的科技水平只能做出这样的计算机),我们只拥有一种能识别0,1硅材料组合的计算机,这种硬件上的裸机是可编程的,写上0,1的纸带是可以给裸机编程驱动它工作的,编程也的确可以做到机器内部,然而这未免太折磨人.如果不改造这二个东西,计算机将会是一个毫无生气的世界.除了在软件上提出一种像样点的高级机器解决机器的问题之外,我们还得需要一种能脱离了机器层面的编程工作.即,我们要同时改造平台和语言,那么熟先熟后呢?几种编程模式 先不说解决平台还是语言的问题谁先谁后,至少,通过上面的讨论,我们得出纸带,机器语言和裸机是这样的组合的第一步,以前的机器都是用这种机器指令驱动的,硬件程序员用0,1编程,我们在前面讲到了这种局限性,这种局限性不光来自语言,还来自硬件平台的低级性(它也导致在这种平台上不可能有什么高级形式的语言),1950s早期,数学家Grace Hopper 发明了symbolic语言,即assembly.这种语言使人们用助记符的形式替代传统的直接写0,1的方式,然而,它只解决了问题的一部分(它还是机器语言,解决的还是低级的硬件问题),我们在前面也一再提到了会编语言编程中出现的所有几大问题:机器功能不够强大,指令由人驱动太麻烦,指令执行需人看管,不受机器托管 所以,我们要提供一种高级映射手段(和程序执行的安全环境),降低人管理机器的任务(一切做到软件层),编程语言之系统实现语言,将编程作为系统软件做到系统内,用编程发明系统本身。所以,为什么需要高级软件平台,高级语言?为什么需要高级语言作为系统实现的映射手段?所有这些,并非没有理由。直到在为机器引入了一个OS后,问题才慢慢明朗.因为出现OS,就可能出现一门对应的高级系统编程语言。在出现了OS之后,人们对系统的开发工作当然也不再满足它是汇编(当然最初的OS就是用汇编写的).如果说机器语言或汇编语言是严格基于平台逻辑的,那么高级语言基于严格的语言机制和语言语法,具有严格的图灵装备,负责产生后来的逻辑和用户级的应用逻辑.所以我们必须得先抽象了一个OS,我们还得给自己造一个高级的开发过程.于是这种系统也可以用这种语言来重写10.这样的模式就是在OS下设计一种高级编程语言.用高级语言编程的方法来解决开发上的问题还是50年代后期业界才想到的事11.从汇编到高级语言,步伐几乎一前一后紧逼(汇编1950s早期,最初的高级语言被发明在1950s后期,.),C语言的前身BCPL语言就是那个年代出生的.那么,为什么需要高级语言呢?这是因为它实在太“好”了,为什么呢?如果汇编开发模型这个模式被另外一种更高明的方法,比如,高级语言代替了,我们就可以专注于正在写的代码和正在用代码表达的应用,高级程序员只需要在语言提供的某种设施上,比如类型上,开始工作,而不用管编译器在背后为你做了哪些把类型映射为位的工作,也不用管OS是如何为你的程序提供一个执行路径的.于是,OS,高级语言,基于OS上的使用高级语言完成的,系统实现与开发,这种编程模式就出现了,这是我们现今主要的编程模式。于是,编程能解决问题的模式是受运行模式控制的,对应用进行编程层面的设计模式是受语言模式控制的,而语言模式是受代码模式控制的.语言模式这里又涉及到一个语言模型的问题.任何语言都并非凭空出现,而是跟运行模式相关的,图灵机上能运行“算法”,图灵机上的语言,它们所产生的作品,必定是一些本质上是算法的东西。图灵证明了,任何一种图灵机,它都能识别与它等价的图灵机能认识的所有符合集。图灵机对于编程的意义在于:它为带有存储装置的形式语言的发明提供了理论,记住,这不是针对计算机的,冯氏理论只是迎合图灵机能处理的东西,而物体化的一台机器。以上,就是图灵机与图灵语言所表现的算法之间的关系。为什么开发模型跟机器模型跟是紧紧联系的呢?而且历史上存在很多失败的计算机模型(死亡计算机协会),只有冯氏模型下的高级语言活了下来.汇编语言的模型只是用指令直接形成电器化指令控制计算机本身(完成“操作系统”的任务),或控制计算机完成计算(“用户任务”),高级语言因为其建立在OS上(此时的语句,是以源文件为载体,而不是电器化的tty),OS可以完成控制计算机本身,os上的(高级)语言模型,就是从汇编发展而来,结构化的语言(比如C语言赋值,流程等),以后所有的改变,比如OO语言,其实际上正是在结构上发展而来的.是以结构化为基础的.如果说机器之于指令,是一种“冯氏计算”(内存修改器,它的本质是迎合冯氏计算机数据处理本质的),建立在OS上的高级语言导面的“语句语义”,它对OS,也要是“数据处理”.这就是直接取材于会编语言的,高级的“指令”,即“过程化语句语义”.这就是说,因为语言写出来的软件就是为了系统服务12,(比如结构化程序语言符合堆栈机),所以这个系统最好就是基于某种语言的,(但冯氏模型太屈就通用的低层实现而不是高层开发抽象,所以它导致了C,C+这样的以类型化和数据化作为设计手段的开发方法),语言逻辑即系统逻辑,这多好啊(从这方面看,图灵机既是计算机模型也是语言模型是很容易理解的),那么为什么我们的PC不设计成与语言直接对应的机器呢,这是因为开发虽然对于PC很重要,但做其它工作时需要PC提供其它通用机制,因此不能仅仅屈就开发模型(比如还屈就机器实现难度上面谈到,CPU+OS才是开发的低级平台,很多软件需要在这个平台上工作而不总是那些高级虚拟机的应用).虚拟机与脚本语言也是一样的道理.而一般虚拟机作了高级逻辑,比如GC等,而X86不可能在硬件架构级就用了GC,如果CPU芯片可以用硬件加速的方法直接支持语言的垃圾回收机制就好了,这要求语言跟CPU一一对应,而且OS也提供了大局方面的GC(并不仅仅针对某个语言,比如WINDOWS的操作系统级的资源释放)在继续操作系统的话题之前,请先复习前面章节讲的机器语言的初级封装形式,即汇编.并确认你大概了解它的原理语言模型用于实现平台模型我们前面谈到编程层面,其实都是三个因素的组合,即执行层面,语言层面,和设计层面.那么,出现了OS与高级语言,系统编程,这三者的组合是一个什么情况呢?语言与OS的关系就是一个系统与系统开发的关系.一般把语言对CPU+OS的开发称为Native关系,提到native还是非native是要涉及到语言的(但最终的说法是:native是native host,而不是指native language),比如Windows是用C来开发的,那么C语言写的源程序相对这样的OS就称为原生的.我们在第一章中谈到的最初级编程是靠描述机器运行,而这里出现了OS,系统编程就成了描述软件运行原理,来支持应用和想要表达的逻辑.CPU与OS的关系(进而影响到开发的那些东西),该如何理解呢,首先,OS的许多东西,是CPU硬件加速下的结果.比如Windows和linux都支持内存分页机制和保护模式,但如果CPU没有提供对这种模式的直接支持(实模式,x86虚拟模式,保护模式中的保护模式),那么在OS级虽然即使可能可以在软件级实现一个所谓的保护模式(但却没有直接硬件的支持)如果说CPU控制了计算机硬件上的一切,OS就相当于控制了软件上开始的一切,并给程序提供了执行路径为基于OS之上的开发提供了可能(这是一种硬生生,有限的机制和基础设施),Posix就相当于OS的外层调用策略(活动,可变化,可组合的策略)和接口13.它把OS的一系列软件逻辑逻辑,进一步封装为软件上可用于开发的那些东西.Posix是类Unix系统(Windows也是符合这个标准的)的接口标准14,为了移殖方便而提出的,因为OS上的用户程序实际上是一种系统调用例程的抽象,硬件被经过OS抽象之后形成了进一步的进程逻辑,Sokcet逻辑等.是最初软件逻辑产生的地方,那么这个系统调用例程就规定了“计算机软件反映到开发上能做的事”,是最初系统编程逻辑产生的地方.C语言作为系统编程的代表语言,它的标准库里面的函数,实际上是站在硬件逻辑和OS平台逻辑上面的一个通用接口.在Windows和类Unix上都是这个抽象接口.支持C标准库的OS必须声明它支持这些接口.方能让标准C语言移殖其上.C+的作用有二.任何判断都是留有发展余地的,我曾说过,代表一门语言性质的最根本,是它的类型系统,但是,最最根本的,是它的类型所在的宿主.语言只是一个开发层面,而不是功能层面,机器才是.或软件的OS.语言解决2个问题,1,什么宿主,能干什么,2,什么设计手段帮助1做得更好.所以,如果改变C+的better c,那么C+根本就不是系统编程语言.而只是一门unnative的shell语言.对于用C开的OS,它的系统编程语言只能是C系语言,其它语言都是脚本语言.native不native就是封装式开发,和实际开发的区别以下:放到移殖那一章 native语言服务于这种语言写的系统,而VM语言服务于虚拟机15(其实Native是相对的概念,比如Java程序相对于Jvm平台就是Native,JPython也是,但是一般还是把win32加x86作为真正的Native).高级语言及高级编程方式(相对汇编和机器编程)到底是什么东西,相信现在不难理解了编程语言编程语言终于,从编程我们谈到了编程语言,即便是这个过程也是不容易的。无论如何,我们总算知道,对编程任何一个子领域的讨论,都不可能滤掉它与编程工程中其它因素:平台,人,应用等的联系,但在上面,我们仅是用平等的眼光去看待那些概念(因为要解释“什么是编程”,当时我们仅仅把它们规范在编程这个大体系下),并仅是粗略地给出了关于其中的联系和联系主体的描述性表格。所以,在接下来我们集中精谈属于映射工程的编程语言时,我们会额外精细地讲解它们与语言的关系。这其中,平台因素对语言的影响最大;平台与语言计算机都是基于某种形式系统的理论基础的(这正是本书第一章开始就要解释的问题),而且它是有架构的,计算模型都是通用系统解决通用问题的,语言和语言系统也是,特定的计算模型决定了这种平台上都有什么语言存在其上(比如冯氏机上的类型语言,Lisp机上的表处理语言),所以了解你正在处于的平台,是你使用这个平台上的某种语言来解决问题的前提.即,平台模型,计算模型是和语言模型相联系的,你首先要明白的,就是要把平台看成是执行系统加编程支持系统的综合.才能更好明白这种平台下语言系统和开发的由来.而对编程的有效学习,是注定要明白这些关于系统的东西先,才能明白后来的东西的一个过程.而系统本身由C写成,C在语法语义级所呈现出来的那些东西,对理解open source的Linux是一个巨大的工具.于是可以产生以下一张图:注:当然,汇编也有保护模式下基于OS的编程,表示一个抽象过程,而且,我们这里谈到的语言都是命令式语言,而非函数式或逻辑式我们来解释三种编程和其中出现的一些词汇(在以上图表中被加粗的部分),由于这些词汇是放在以上这个大唯度中被讨论的,所以对这些词汇的讲解本来就是站在了它们一产生时的那个大角度的.(而我们本书就是按这个大思路写的,这个大角度大唯度保证了:只要我们写完了这里面出现的这些东西,实际上就谈完了关于编程的几乎一切东西,而且,因为这些唯度道出了这些东西产生的本源,所以是沿着一条正确的学习曲线来的).三种编程原始的编程:不同的编程还是不同的,甚至有着本质的差别,存在三种编程,即未经抽象的编程(或原始的编程),此时的程序执行体是裸机,编程支持也是汇编,裸机是整个计算机在硬件级基本能执行程序的本形,此时并没有出现任何软件上的东西(包括软件上的执行系统,所以更不可能有除了执行功能以后的其它系统功能的软件概念,比如软件上对编程的支持),机器的这个状态跟指令和汇编语言有关,由于没有出现任何软件的概念(我们把出现OS作为拥有软件意义的标志),本书开头处就把握好这个机会,谈了三个方面的内容.即,裸机中CPU与内存是如何作为硬件二大主体进行工作的(主要是执行指令调用数据和实现跳转,所以说冯氏系统是顺序串行的确定的,确定就是说,它是预定义的,它一定是被预先生成为顺序的),汇编语言是如何在CPU加内存的工作方式下天然地引入了那些指令,以及它基于指令选择的初级编程层面模拟sub例程的方式(这是完全没有语法意义的),然后谈到裸机加汇编语言的组合是低级的平台加编程的组合方式(平台模式和计算模型的一个组合),是注定要被改变的.抽象了的编程,程序执行体是软件的OS,编程支持是高级语言,解决问题的方法上实现了数据结构和算法这使编程语言按集成的抽象度分为二种,一种是C这样的实现语言,它主要面向系统本身,利用实现逻辑的数据结构和算法(之所以称数据结构和算法是实现逻辑,因为它们解决问题时使用了组织内存的手段,而内存,是初级系统级的东西),解决的是系统编程问题,上面说了,系统软件,包括OS和编译器的制造与设计,都是不断被证明可以用数据结构和算法的那些知识很好解决的一类问题的典型,人们说系统程序员是幸福的,因为系统程序员只需掌握有限的固定的系统知识成型的标准理论,和C这样的语言,外加数据结构和算法以设计和解决问题的手段就行了.高度抽象了的编程,程序执行体是虚拟机,编程支持是某种工业成熟的高级虚拟机语言(往往它们把执行体和语言作为它们的标准),而且在抽象了数据结构和算法的基础上,语言还把设计模式这样的越来越高级的编程理念加入其中.语言与应用之间是紧密相连的,不同的语言解决不同层次的问题,有的语言善于解决,这就跟语言内提供了什么样的设计方法,它的语言内核中内置了什么样的语言元素,这些元素是Python这些的高抽象语言内置的,它面向比系统问题更复杂的现实问题,涉及到新的框架(比如web)新的理念,涉及到很多与设计与设计模式有关的东西,还涉及到高抽象的语言.虽然这些东西名为“抽象”,但实际上,还是要求程序员对所有这些抽象前面的铺垫知识有一个大概理解的.语言选择解决了“什么是编程”,什么是编程语言,我们终于可以稍微向更高级一点的问题,比如“怎么样编程”这样的问题前进了。为了编程,固然得学一门语言,然而语言与语言间又是不同的,这种不同会直接地影响到你选择的语言是否正是你要表达的应用所需要的,而且会影响到你学习这门语言的曲线长短,那么对于初学者来说,什么是真正最简单最实用的语言呢?历史上地,编程为了越来越抽象(以更好表达应用,或满足人们使用某种语言进行更好设计的要求,实际上这二者也并非毫无联系),发展出来一系列历史抽象,比如数据结构和算法,VM,语言的语法和语义,设计模式,等等,对某阶段的编程需要涉及到的东西各有不同(因为它们处在高低不同的层次上,解决实现或设计的偏向程度不一样),低抽象的编程只需理解某种固定的平台细节和语言,解决常见的系统内编程,而高抽象的语言及编程,使编程工作进入一种复用和设计多于自己实现轮子的现状,此时他们面向解决应用问题居多,自然开发语言应直接内置某种高级语法语义,或库标准,或设计模式,这些就可以不必事事重新发明轮子,重复那些在低编程阶段就不断反复解决过了的问题(比如,高级开发可以使用直接形成标准的IO,GUI,任务逻辑,或高级数据结构).这二种编程学习曲线自然不可相比.处在二个极端的C和Python,C是典型的实现语言,而Python是典型的高级抽象的语言.(C+的better c+OO层次组成的语言,是介于C和Python之间的中间语言)以同样的应用高度来说,由于c本身不够抽象,所以由C到语言到应用,中间经过了太多抽象,理解曲线过于曲折,相比Python来说,语言到应用中间的抽象相对少一点,学习Python开发的学习曲线要平滑一点,C太靠近描绘底层,细节太多,而C+除了用C的底层能力来描述数据结构它还加了一层设计和代码结构逻辑,它假设人们只需要在高层次懂它的设计就可以编程了(于是它给人们一种这样的假像:即C+进行对系统的编程不再需要涉及到系统低层,言下之意这是跟C比较而言的),但实际上理解这种OO设计本身也需要对高层次下面层次的理解.Python学习曲线短,是因为它能迅速看到正确的程序结果,让学习者明白,而C,需要做太多的工作除了C+和Ada,目前的语言都不具有泛型,目前绝大多数语言都是为了运行期16而准备的,所以,学编程,第一件事,就是学习运行时的栈,和运行时的数据(这也是本书程序二大部分,在第一部分先讲系统环境,系统环境中程序的执行路径,然后再讲具体的语言机制和某门语言,这样的步骤的由来),因为运行期语言对它们都做了编程机制上的直接封装.这里只稍微谈一下语言之争,更多的请参照附录部分的语言之争。因此存在大量争论。语言与平台,应用,设计是密不可分的,作为软件工程中的编程,需要讨论它在结合所有这些因素时所表现出来的综合优势,而这种因素只能是因语言不同的。这是从语言的外部环境比较。从语言内部来说,因为语言是由类型系统和运算系统组成的,所以对一门语言能力的讨论,总是要涉及到它对数据结构的表现能力和对代码的抽象能力,以及对问题本身的抽象能力17,首先来说数据结构,现今的编程都还只属于某种未脱离数据处理模式的语言(冯氏下的编程就是数据抽象加数据结构抽象,这些都对应着冯氏机作为处理数据的机器的本质.而代码,实际上在冯氏机里也是作为数据被对待的,这就是本节一开头谈到的问题)还未脱离运用处理数据的方式来解决编程以解决问题的方式.所以,对数据结构和算法的运用永远是一门冯氏下的语言编程所要涉及到的(只要这个过程未被设计完全抽象掉).再来说语法-1.每个人心中都有一个“编程”,因为每个人所处的维度都不尽相同 2.在堆栈机上,程序执行即很深的堆栈嵌套 3.比如可重定位代码,从内存的眼光来看,它们也是数据,只是他们活动起来,就成了执行路径中的递归堆栈,而且,带有程序上的子程序抽象的意义 4.编程,准确的说法是“语法编程”,所以编程还要解决以何种语法的语言来进行的事,不可能为每种应用写一个DSL.即现代的编程还不是语义编程或应用编程.使用什么样的语法,根本上取决于使用什么样的语义,但语义又是语言相关的,所以选择语言,是一件大事 5.oo已经变成了一种基础,而不是编程界可有可无,可以替代的东西.6.这个人可能是程序员,脚本程序员,或产生软件需求及制定设计的非专业用户 7.我们在这里提到用户,说明它不是程序员,也甚至不是脚本程序员,而普通意义上的程序员,只是一类实现者,它同时接上了机器的C逻辑和对于用户和设计者的设计逻辑,一般地,现今的程序员都是利用某种面向运行期的语言进行某种类型编程type programming或abstract type programming.8.程序设计语言的选择非常重要,它将影响人们理解问题的出发点 9.应用中的系统问题,强烈跟语言和系统有关,所以我反而把它们放在了书的前面.整书的后半部分才着重讲解设计与应用相结合的地方.10.C和unix的关系是最好的说明.在设计一种平台时,语言和OS是一个架构的基础部分,应用再在这个上面慢慢搭建.参见Google手机平台.如果你看过Google的手机平台设计,就会发现语言这个图灵装备GLIBC往往是架构的最基础部分.11.放大到整个人类,任何现在看起来自然而然的事情,人类可能在那时都有过不小的脑筋转弯期 12.语言被发明,第一件事就是它必须可以用于开发系统本身.所以这到底是鸡生蛋还是蛋生鸡呢?这个鸡与蛋,是具体的鸡与蛋,而不是泛义的。故,是先有鸡,后有蛋。13.这里有