命令式,过程式和结构化编程之间有什么区别?


85

通过研究(书籍,维基百科,关于SE的类似问题等),我了解到命令式编程是主要的编程范例之一,您在其中描述了一系列要由计算机执行的命令(或语句)(因此,要求其采取特定措施,因此命名为“命令性”)。到现在为止还挺好。

另一方面,过程式编程是命令式编程的一种特定类型(或子集),您可以在其中使用过程(即函数)来描述计算机应执行的命令。

第一个问题:是否有一种非过程式命令式编程语言?换句话说,没有程序就可以进行命令式编程吗?

更新:第一个问题似乎已得到解答。语言可以是必不可少的,而无需程序化或结构化。一个示例是纯汇编语言。

然后还有结构化编程,这似乎是命令式编程的另一种类型(或子集),它的出现是为了消除对GOTO语句的依赖。

第二个问题:过程式编程和结构化编程有什么区别?您能否拥有一个没有另一个,反之亦然?我们可以说过程编程是结构化编程的一个子集吗?

在此处输入图片说明

Answers:


52

许多术语可以在编程语言中重用(经常被误用),尤其是那些面向对象的语言。

这里是这些术语的一些小描述。

  1. 命令式编程-在过去的好日子里,当编程广泛地汇编时,代码将具有大量的GOTO。甚至像FORTRAN和BASIC这样的高级语言也开始使用相同的原语。在此编程范例中,整个程序是单个算法或逐步线性编写的完整功能。这是势在必行的风格。理解即使使用现代C语言,也确实可以编写完全糟糕的命令性工作,但是用高级语言组织代码非常容易。

  2. 结构化和模块化编程-大多数情况下,我们应该可以互换使用但有细微差别的术语。当高级语言开始变得更加丰富时,人们意识到应该将所有工作单元分解为较小的易处理部分-也就是说,当函数出现并且编程成为函数的层次结构时,许多较低级别的语言可以重新使用。

    • 结构化编程是将功能划分为类似for loop, while loop, if... then块结构的单元时的任何编程。
    • 同样,这里的一段代码(函数)可以重复使用。
    • 模块化编程中,可以创建一种物理形式的程序包-即可以装运的一大堆代码;这是相当通用且可重复使用的。这称为一起编译的元素模块
    • 因此,几乎看不到没有结构化的模块化程序,反之亦然;技术定义稍有不同,但是大多数结构化代码都可以模块化和其他方式制成。
  3. 随后出现了在文献中定义明确的“面向对象程序设计”。理解面向对象的编程定义的结构化编程一种形式。所有那些基于功能的代码(结构化代码但面向对象)的新名称通常称为过程编程。

    • 因此,将函数(或过程)主导数据的基本结构化代码称为过程式,而基于类和对象的表示形式则称为面向对象。根据定义,两者都是模块化的。

许多人认为-所有结构化编程(可能跳过基于对象的编程)都是命令式编程;我猜这仅仅是由于缺乏对命令式编程的明确定义-但这是错误的。当您没有进行必要的操作时,您正在进行结构化编程!但是我仍然可以在C或FORTRAN程序中编写很多函数以及很多goto语句来进行混合。

具体到您的问题:

第一个问题:纯汇编语言是命令式语言,不是结构化或过程式的。(具有逐步的解释性控制流并不意味着程序性,而是将功能划分为功能才是语言程序性的原因)。

  • 更正*大多数现代形式的汇编DO都支持使用功能。实际上,高级代码中所有可能的东西都存在于低级工作中。尽管创建过程代码是一种更好的做法,但是可以同时编写过程代码和命令性代码。与后者不同,它更易于维护且更易于理解(避免使用可怕的意大利面条式代码)。我认为,有一些shell / bash脚本更适合纯粹地当务之急,但是即便如此,大多数脚本还是具有功能的,开发人员肯定会了解它们具有多少价值。

第二个问题:过程编程是结构化编程的形式


奖金

  • 根据某些分类法,主要分类是声明式(或功能性语言)与命令式。声明性语言允许在不描述其控制流程的情况下进行计算,而命令式语言定义了明确的控制流程(逐步)。基于这种分类,命令式编程(对于某些人)可以是结构化,模块化和OO编程的超集。参见:函数式编程与OOP

  • 面向对象之后,还发明了其他编程范例:有关更多详细信息,请参见此处:面向方面,面向主题和面向角色的编程之间有何区别?


1
因此,您是否会说过程编程也一定是结构化编程,而事实并非相反(尽管通常如此)?
丹尼尔·斯科科

2
是的,我会这样说。
Dipan Mehta

1
在我的回答中,我定义了命令式与结构化-命令式编程仅通过逐步执行而编写,而没有结构化。但是,根据某种定义,还有另一种分类;这是声明式(或功能性语言)与命令式之间的分类。声明性语言允许在不描述其控制流程的情况下进行计算,而当务之急是定义显式控制流程(逐步)。基于这种分类,命令式编程(对于某些人)可以是结构化的超集。有些人不太遵循这个定义。
Dipan Mehta

关于结构化编程的定义,我有不同的看法。结构化编程和模块化编程不是一回事。请参阅本说明末尾的定义。相同的链接表明Assembler **是一种结构化的编程语言!STP定义的参考:en.wikipedia.org/wiki/Structured_programming – Emmad Kareem
NoChance 2012年

是“包的物理形式” ...文件,还是文件的目录/归档?(或者不是,而是其他。)
n611x007 2012年

4

第一个问题:是的,许多纯面向对象的语言都有资格。尽管它们具有与功能非常接近的方法,但是他们从消息的角度看待这些方法,并且没有赋予它们足够的权重来调用语言过程。

第二个问题:差异通常在不同的范围内。您可以在各处使用带有goto语句的函数,该函数将采用过程样式,但不能采用结构化编程。另一方面,大多数面向对象的语言支持并鼓励结构化编程,但不支持过程编程。

程序编程描述了程序的全局顺序。程序程序是通过查看调用图可以最有效地理解的程序。结构化编程是一个本地属性,它适用于if和while的使用,而不是goto的使用。

因此,这两个属性是分离的,您可以拥有一个而没有另一个。


1
程序化的唯一试金石是该语言包含过程(函数或方法)并且是命令式的,即。非声明性的。这意味着大多数非纯功能的OO语言都将是过程语言。
Dietbuddha 2011年

1
@dietbuddha:根据这个定义,Haskell将通过使用monads成为程序语言。我需要一定程度的依赖程序才能使语言程序化。
thiton

我不太了解Haskell,但我认为Haskell是一种纯函数式语言,因为它在Monads中包含了副作用。
Dietbuddha

2
好吧,有人声称Haskell并不是纯粹的功能,因为它允许与外界进行任何交互(或者因为GHC的扩展名unsafePerformIO可以使人恶心)。其他人则嘲笑Haskell是他们最喜欢的命令式编程语言。但是事实是,很大一部分的Haskell代码与其他代码完全分开IO,没有使用非标准漏洞来掩盖副作用,并且纯粹是功能性的。

1
@thiton我不同意。Monad也是功能构造;由于Haskell的语法糖(“表示法”),它们仅显得势在必行。当您对糖单核糖进行脱糖时,它们的功能性质变得明显。相反,OO语言确实是必不可少的:它们的核心是基于语句的顺序执行。
安德列斯·F

2

在过去的50年中,大多数流行语言都是围绕流行的计算机体系结构(即冯·诺依曼体系结构)设计的,该体系结构的创始人之一是约翰·冯·诺依曼。

这些语言称为命令式语言。

在冯·诺依玛(von Neumaan)计算机中,数据和程序都存储在同一内存中。执行指令的CPU与内存分开。因此,指令和数据必须从内存传输到CPU。CPU中的运算结果必须移回内存。自1940年代以来建造的几乎所有数字计算机都基于von Neumaan架构。


1
+1不确定这与问题有什么关系,但这是一个有趣的答案。
Chuck Conway 2012年

2
什么?命令式与程序式等内容在哪里?
bbqchickenrobot

我认为这里的要点是,对程序结构(命令性,声明性,过程性,面向对象,功能性等)的质疑是语言构造,并且所有程序最终都在冯·诺依曼体系结构机器上处理。这类似于说所有图灵完成语言都是等效的。
ChuckCottrill

2

恐怕到目前为止,给出的答案都无法很好地抓住概念的核心。

命令性,过程性和结构化不是互斥的属性,它们仅关注建模逻辑的一个方面。

祈使式是声明式的对立部分祈使式基本上是指您让计算机执行您提供的一系列指令来告诉计算机该做什么。另一方面,声明式程序告诉要实现的目标。换句话说,定义步骤与定义结果。

程序性编程是指处理器(硬件或解释器)将指令包装为复合内容,跳转至该复合内容并在执行复合内容后返回至跳转后的点的能力。这听起来似乎是微不足道的,按照今天的标准来看,这是微不足道的,但是您需要在计算机中获得一些基本的支持,然后才能执行此操作:跳转的能力,某种将地址压入其中的堆栈可以弹出并跳转到稍后再跳转。堆栈指针。微处理器很快就提供了此功能,但是您可以想象一个原始处理器只能像序列带或穿孔卡处理器那样顺序执行向其提供的指令。

结构化编程是从跳转到另一条指令的能力的下一步。最终,一切都会归结为跳转,但是如果您可以进行条件跳转,则可以构建基本的控制流语句,如if-then,for,while,repeat-until和switch。应用这些称为结构化编程。

在任何现代编程环境中,您都可以使用上述所有内容,并且将它们视为理所当然,因此我们不再赘述。语言之间的差异性已经长期转移到更高层次的范例,例如面向对象和函数式编程。

但是,声明性编程仍然并不常见,主要是因为它至少在一定程度上始终是特定于领域的。您不能使用通用的声明性语言。这就是为什么我们仍然坚持使用所谓的第三代语言,而声明式编程或“建模”将被视为第四代语言。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.