程序设计中的基本概念
程序(Program)告诉计算机应如何完成一个任务的一组指令( A set of instructions),用于指定操作、操作数和处理必须遵循的顺序。
电脑程序设计(Computer programming),或称程序设计(programming),是给出解决特定问题程序的过程,程序设计往往以某种程序设计语言为工具,给出这种语言下的程序。程序设计过程一般包括分析、设计、编码、测试、调试等不同阶段。
编程语言(programming language)又叫程序设计语言(program design language, PDL),是用来定义计算机程序的形式语言。泛指一切被标准化用来向计算机发出指令系统。如C、python等。一般分类:
☆机器语言:指挥计算机完成某个基本操作的命令称为指令,所有指令集合称为指令系统,直接用二进制代码表示指令系统的语言称为机器语言,早期计算机采用机器语言,只能识别0和1。
☆汇编语言:汇编语言的实质和机器语言是相同的,都是直接对硬件操作,只不过指令采用了英文缩写的标识符,更容易识别和记忆。它同样需要编程者将每一步具体的操作用命令的形式写出来。
汇编程序通常由三部分组成:指令、伪指令和宏指令。汇编程序的每一句指令只 能对应实际操作过程中的一个很细微的动作,例如移动、自增,因此汇编源程序一般比较冗长、复杂、容易出错,而且使用汇编语言编程需要有更多的计算机专业知识。
☆高级语言:高级语言的出现使得计算机程序设计语言不再过度地倚赖某种特定的机器或环境。这是因为高级语言在不同的平台上会被编译成不同的机器语言,而不是直接被机器执行。
高级语言是目前绝大多数编程者的选择。和汇编语言相比,它不但将许多相关的机器指令合成为单条指令,并且屏蔽了与具体操作有关但与完成工作无关的细节,例如使用堆栈、寄存器等,这样就大大简化了程序中的指令。
高级语言所编制的程序不能直接被计算机识别,必须经过转换才能被执行,按转换方式可将它们分为两类:
解释类:执行方式类似于我们日常生活中的“同声翻译”,应用程序源代码一边由相应语言的解释器“翻译”成目标代码(机器语言),一边执行,因此效率比较低,而且不能生成可独立执行的可执行文件,应用程序不能脱离其解释器,但这种方式比较灵活,可以动态地调整、修改应用程序。
编译类:编译是指在应用源程序执行之前,就将程序源代码“翻译”成目标代码(机器语言),因此其目标程序可以脱离其语言环境独立执行,使用比较方便、效率较高。但应用程序一旦需要修改,必须先修改源代码,再重新编译生成新的目标文件(* .OBJ)才能执行,如C++。
【计算机中的语句(statement)和指令(instruction)
语句(statement)
在计算机科学的编程中,一个语句是指令式编程语言中最小的独立元素,表达程序要运行的一些动作。
计算机指令(computer instruction)就是指挥机器工作的指示和命令,程序就是一系列按一定顺序排列的指令,执行程序的过程就是计算机的工作过程。
在计算机的汇编语言中,每条语句(statement)通常对应于一条单处理器指令(processor instruction)。在高级语言中,语言语句通常(在程序编译后)产生多个处理器指令。
在计算机程序设计中,语句(statement )是程序设计语言的一个语法单元,它表示要执行的某些操作。用这种语言编写的程序由一个或多个语句的序列组成。语句可以有内部组件(例如表达式)。
平台(Platform)这个词可以指计算机体系结构(Architecture),也可以指操作系统(Operating System)。
不同的计算机体系结构(硬件平台)有不同的指令集(Instruction Set),可以识别的机器指令格式是不同的,直接用某种体系结构的汇编或机器指令写出来的程序只能在这种体系结构的计算机上执行。
除非特别强调,语句和指令在程序设计领域一般不加以区分(作为同义语用)。
计算机程序(Computer Program)和代码(code)
计算机程序(Computer Program)是指未经编译的,按照一定的程序设计语言规范书写的,人类可读的文本文件。
代码(code),就是程序员用开发工具所支持的语言写出来的源文件,是一组由字符、符号或信号码元以离散形式表示信息的明确的规则体系。
一般不加以区分。
工程(Project,工程、项目)
一个较大的程序(也可以说软件)往往包含多项功能,代码的编写和维护也将变得非常困难,为此一些编程工具引入工程(Project,工程、项目)概念。在使用部分编程工具时,会先要求建立工程,对代码文件、相关资源文件(图片、视频、音频、库等)进行管理——一般表现为分门别类的放入不同的文件夹(目录),可以便捷的管理,比如重命名、删除文件、编辑文件等。
文件(File)
计算机文件是以计算机存储器如硬盘为载体存储在计算机上的信息集合。以文件名为标识,文件名由基本名称(主名)和扩展名组成,中间用点(.)联结,基本名称由用户给出,扩展名用来标明文件的类别或格式。
文件和文件夹
1、文件是有具体内容或用途的,通常电脑有多种不同功用的文件,有可执行文件,数据文件,类或库文件,文本文件,图像文件等等数不胜数。
2、文件夹(Folder)也称为目录(Directory)是用来放置这些文件的,而且可以分成许多级。在一个目录中的另一个目录被称作它的子目录(子文件夹)。这样,这些目录就构成了层次(hierarchy),或树形结构。】
算法(Algorithm)
算法(Algorithm)是指对某些问题的严格的解决方法和步骤,一般的,一个算法拥有以下特点:
有穷性:算法必须保证在执行有限步骤后结束。
可行性:算法是确切可行的,即使在数学中,该算法可行,但若在实际应用中,程序不可以被执行,那么 ,该算法也是不具有可行性的。
确切性:算法的每一个步骤必须具有明确的意义。
输入:一个算法必须要有0个或多个输入。
输出:一个算法必须要有1个或多个输出。
描述算法的常用的方式方法
☆自然语言
自然语言(Natural Language),就是人们日常生活中所使用的语言,可以是中文、英文、法文等等。用自然语言辅以操作序号描述算法,优点是通俗易懂,即使读者没学过数学或算法,也能看懂算法的执行。算法3.1就是用自然语言描述的。
自然语言固有的不严密性使得这种描述方法存在以下缺点:
(1) 算法可能表达不清楚,容易出现歧义。例如,“甲叫乙把他的书拿来。”,是将甲的书拿来还是将乙的书拿来?从这句话本身难以判定。
(2) 难以描述算法中的多重分支和循环等复杂结构,容易出现错误。
由于上述缺点的存在,一般不使用自然语言描述算法。
☆流程图
流程图(Flow Chart)是最常见的算法图形化表达,也称为程序框图,它使用美国国家标准化协会(American National Standard Institute,ANSI)规定的一组几何图形描述算法,在图形上使用简明的文字和符号表示各种不同性质的操作,用流程线指示算法的执行方向。
常见的流程图符号如下图所示:
图中各流程图符号具体含义如下:
起止框:表示算法的开始或结束;
判断框:表示对一个给定的条件进行判断。它有一个入口,二个出口,分别对应条件成立与否的不同执行方向;
输入输出框:表示算法的输入、输出操作;
处理框:表示一般的处理操作,如计算、赋值等;
注释框:非算法部分,用于帮助理解算法;
流程线:用流程线连接各框图,表示算法的执行顺序;
连接点:连接点总是成对出现,同一对连接点标注相同的数字或文字,用于将画 在不同地方的流程线连接起来,从而避免流程线的交叉或过长,使流程图清晰。
用流程图描述欧几里得算法如下图所示:
流程图描述算法简单、直观,但修改麻烦,使用者可以在流程图上随意画流程线,使其常常非结构化。因此,结构化程序设计语言出现之后,对流程图的依赖逐渐降低。流程图适用于描述非常简单的算法,对复杂算法的描述非常不便。
应用范围
流程图不但用于帮助计算机程序的开发中,而且还可以用于其他领域。在工商业中使用流程图来表示制造以及工业操作图示化。流程图被广泛应用于帮助人们图示化过程以及发现过程中的缺陷。
使用方法及步骤
流程图的使用方法非常的简单,将你要完成的一件事情从开始到结束的所有过程细节都用流程图的符号和箭头画出来就可以了。
☆伪代码
算法最终是要用程序设计语言实现并在计算机上执行的。自然语言描述和流程图描述很难直接转化为程序,现有计算机程序设计语言又多达几千种,不同的语言在设计思想、语法功能和适用范围等方面都有很大差异。此外,用程序设计语言表达算法往往需要考虑所用语言的具体细节,分散了算法设计者的注意力。因此,用某种特定的程序设计语言描述算法也是不太可行的。伪代码描述正是在这种情况下产生的。
一般来说,伪代码是一种与程序设计语言相似但更简单易学的用于表达算法的语言。程序表达算法的目的是在计算机上执行,而伪代码表达算法的目的是给人看的。'伪代码('Pseudocode)应该易于阅读,简单和结构清晰,它是介于自然语言和程序设计语言之间的。伪代码不拘泥于程序设计语言的具体语法和实现细节。程序设计语言中一些与算法表达关系不大的部分往往被伪代码省略了,比如变量定义和系统有关代码等。程序设计语言中的一些函数调用或者处理简单任务的代码块在伪代码中往往可以用一句自然语言代替。例如“找出3个数中最小的那个数”。
由于伪代码在语法结构上的随意性,目前并不存在一个通用的伪代码语法标准。作者们往往以具体的高级程序设计语言为基础,简化后进行伪代码的编写。最常见的这类高级程序设计语言包括C、Pascal、BASIC、Java、Lisp和ALGOL等。由此而产生的伪代码往往被称为“类C语言”、“类Pascal语言”或“类ALGOL语言”等等。
编程范式(Programming paradigm)
编程范式是编程语言的一种分类方式,它并不针对某种编程语言。就编程语言而言,一种编程语言也可以适用多种编程范式。
☆面向过程的程序设计(Process oriented programming),也称为结构化程序设计(Structured programming),有时会被视为是指令式编程(Imperative programming)的同义语。。编写程序可以说是这样一个过程:从系统要实现的功能入手把复杂的任务分解成子任务,把子任务再分解成更简单的任务,层层分解来完成。可以采用函数(function)或过程(procedure)一步步细化调用实现。程序流程结构可分为 顺序(sequence)、选择(selection)及重复(repetition)或循环(loop)。
☆事件驱动程序设计(Event-driven programming)
基于事件驱动的程序设计在图形用户界面(GUI)出现很久前就已经被应用于程序设计中,可是只有当图形用户界面广泛流行时,它才逐渐形演变为一种广泛使用的程序设计模式。
在过程式的程序设计中,代码本身就给出了程序执行的顺序,尽管执行顺序可能会受到程序输入数据的影响。
在事件驱动的程序设计中,程序中的许多部分可能在完全不可预料的时刻被执行。往往这些程序的执行是由用户与正在执行的程序的互动激发所致。
事件驱动常常用于用户与程序的交互,通过图形用户接口(鼠标、键盘、触摸板)进行交互式的互动。属于事件驱动的编程语言有:VB、C#、Java(Java Swing的GUI)、Python基于tkinter的GUI编程等。
事件(event)表示程序某件事发生的信号。事件分为:
外部事件:由外部用户动作产生的事件。例如,点击鼠标、按键盘。
内部事件:由系统内部产生的事件。例如,定时器事件。
系统预定义一些事件类型如按键、点击、鼠标移动等,事件类型代表是什么事件。事件触发时可以运行事件处理代码。
☆面向对象程序设计(Object Oriented Programming),是围绕着问题域中的对象(Object)来设计,对象包含属性、方法。对象则指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关联的数据。在面向对象程序编程里,计算机程序会被设计成彼此相关的对象。
从同种类型的对象抽象出类,但在程序中,必须要事先定义类,然后再调用类产生对象(实例化)。有了类的好处是:我们可以把同一类对象相同的数据与功能/操作存放到类里,而无需每个对象都重复存一份,这样每个对象里只需存自己独有的数据即可,极大地节省了空间。所以,如果说对象是用来存放数据与功能的容器,那么类则是用来存放多个对象相同的数据与功能/操作的容器。
面向对象程序设计的基本概念
类(Class)
(1)类是具有共同特征的对象的抽象。
(2)类是对具有共同属性和行为的一类事物的抽象描述。 共同的属性被描述为类的数据成员,共同行为被描述为类的成员函数。
类是对象(Object)上的抽象,是对象的模板;对象是类的具体化,称为类的实例(instance)。类可以有子类,也可以有父类,从而形成层次关系。
对象(Object)
定义:对象是指客观存在的事物(可以是看得见摸得着的,也可以是看不见摸不着的),由一组属性和方法构成。
对象 = 属性 + 方法
在面向对象程序设计中,对象之间也需要联系,我们称作对象的交互。
属性(attribute 或Property)是用来描述对象的外部特征。
属性的引用方法为:
对象名.属性名 = 属性值 或 变量名 = 对象名.属性名
面向对象程序设计时,描述Class或Object用语:
Description | OOA/OOD | C++ | Java/C# | python | JavaScript | PHP |
Feature特征 【刻画或描述Object的特征 / Class中的变量、常量】 | Attribute | Member Variable | Field | attribute | Property | Property |
Operation操作 【Object提供的服务或操作 / Class中的函数】 | Method | Member Function | Method | Method | Method | Method |
OOA/OOD:object oriented analysis / object oriented design,面向对象分析和设计。
在面向对象理论里,attribute 和Property有时不加区别,有时表达的不是一个层面上的东西,在一些编程语言(如Java、c#)中,property实际上是字段(field)的get/set方法是封装好attribute,并且暴露给外部的一种行为。应根据语境和用途含义区别。
方法(Method)是对某对象接收消息后所采取的操作的描述,它表明了一个对象所具有的行为能力。
调用对象的方法为:
对象名.方法名[参数列表]
【对象(Object)与类(Class)的关系
类是对象的抽象,而对象是类的具体实例。类与对象的关系是抽象与类的实例化就是对象,对象的共性特征抽象出来就是类。
比如车是类,具体的车就是对象 如F1赛车。
比如你要买一台PC,你在订单上列出了这台PC的CPU和显卡型号、显示屏的大小、键盘是104还是87位、PC颜色,这所有信息组成在一起就是类,当服务员拿出了一台符合这个订单的具体PC时,这个PC就是那个类的具体对象。
从同种类型的对象抽象出类,但在程序中,必须要事先定义类,然后再调用类产生对象(实例化)。有了类的好处是:我们可以把同一类对象相同的数据与功能/操作存放到类里,而无需每个对象都重复存一份,这样每个对象里只需存自己独有的数据即可,极大地节省了空间。所以,如果说对象是用来存放数据与功能的容器,那么类则是用来存放多个对象相同的数据与功能/操作的容器。】
面向对象程序设计的三大特征:
封装是基础,继承是关键,多态是补充,而多态又必须存在于继承的环境中,多态的实现受到继承性的支持。
封装(Encapsulation)
定义:
(1)将数据抽象的外部接口与内部实现的细节清楚地分开
(2)封装就是将抽象得到的数据和行为相结合,形成一个有机的整体
作用:
(1)可以隐藏实现细节,使得代码模块化。
(2)封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,特定的访问权限来使用类的成员。
(3)封装主要依靠对类、数据和方法的访问控制,从语法上讲就是加上private、protected、public等关键词。
(4)封装的意义在于保护或者防止代码(数据)被我们无意中破坏。在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改。
继承(InHerit[ance])
继承是类与类之间共享数据和方法的一种机制,被继承的类称为父类,也叫基类或超类;继承的类称为子类,也叫派生类。继承是实现代码重用的重要手段,
定义:
(1)子类可以从父类继承属性和操作,提高编程效率。
(2)通过继承关系利用已有类构造新类。
作用:代码重用
(1)避免代码重复开发,减少代码和数据冗余。
(2)通过增强一致性来减少模块间的接口和界面。
多态(Polymorphism)
定义:
(1)不同的对象收到相同的消息时产生多种不同的行为方式。
(2)多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术。
(3)允许将子类类型的指针赋值给父类类型的指针。
(4)同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
作用:
(1)编译时的多态性
通过函数重载和运算符重载实现。
对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。
(2)运行时的多态性
通过类的继承关系和虚函数来实现。
程序在执行前根据函数名和参数无法确定应该调用哪个函数,必须在程序执行的过程中根据具体的情况来动态确定。
编译时的多态性为我们提供了运行速度快的特点,而运行时的多态性则带来了高度灵活和抽象的特点。
重载(Overload)
定义:将语义、功能相似的几个函数用同一个名字表示,但参数不同(包括类型、个数不同,或两者都不同)
重载与多态是紧密相连的。
☆函数式程序设计(functional programming),顺便指出,不要误认为使用了函数就是函数式程序设计。函数式程序设计(functional programming)或称函数编程,是一种编程范式(programming paradigm),它将电脑运算视为函数运算,并且避免使用程序状态以及易变对象。其中,λ演算(lambda calculus)为该语言最重要的基础,λ演算的函数可以接受函数当作输入(引数)和输出(传出值),主要思想是把运算过程尽量写成一系列嵌套的函数调用。举例来说,现在有这样一个数学表达式:
(1 + 2) * 3 - 4
传统的过程式编程,可能这样写:
var a = 1 + 2;
var b = a * 3;
var c = b - 4;
函数式编程要求使用函数,我们可以把运算过程定义为不同的函数,然后写成下面这样:
var result = subtract(multiply(add(1,2), 3), 4);
函数式编程允许把函数本身作为参数传入另一个函数,还允许返回一个函数!函数式编程强调没有"副作用"(side effect),意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。
在函数式编程中,函数是第一类对象(first class),指的是函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。