C是命令式还是声明式编程语言

时间:2014-02-24 04:05:02

标签: c imperative-programming declarative-programming

知道命令式和声明式编程之间的区别是否可以解释现实世界中两者之间的差异,这是非常令人困惑的?

请澄清C是一种命令式还是声明式语言?

5 个答案:

答案 0 :(得分:18)

C是一种命令式编程语言。

两者之间的一线差异是声明式编程就是当你说出你想要的东西时,命令式语言就是当你说出如何获得你想要的东西时。在声明性编程中,重点是计算机应该做什么而不是它应该如何做(例如SQL),而在命令式编程中,重点是计算机应该采取什么步骤而不是计算机会做(例如C,C ++,Java)。

Imperative programming是一种编程范例,用于根据改变程序状态的语句描述计算

Declarative programming是一种编程范式,一种构建计算机程序结构和元素的方式,表达计算逻辑而不描述其控制流程

许多命令式编程语言(例如Fortran,BASIC和C)是汇编语言的抽象。

wiki说: -

  

作为命令式语言, C使用语句来指定操作。该   最常见的语句是表达式语句,由一个表达式组成   要评估的表达式,然后是分号;作为副作用   在评估中,可以调用函数,也可以调用变量   分配了新的价值。修改正常的顺序执行   语句,C提供了几个标识的控制流语句   保留关键字。 if(-else)支持结构化编程   条件执行和do-while,while和迭代   执行(循环)。 for语句有单独的初始化,   测试和重新初始化表达式,其中任何一个或全部都可以   省略。休息和继续可以用来离开最里面   封闭循环语句或跳过重新初始化。有   也是一个非结构化的goto语句,它直接分支到   功能中指定的标签。开关选择一个案例   基于整数表达式的值执行。

答案 1 :(得分:8)

<强>买者

我写的内容很多,所以请耐心等待。

理论上

C 强制性,因为代码读起来就像是如何做某事的秘诀。但是,如果你使用很多命名良好的函数和函数指针来实现多态,那么可以使C代码看起来像一个声明性语言。

命令式语言中,您专注于算法/实现。工程本质上是必不可少的,因为你专注于流程的效率:在时间或金钱(或CS中的记忆)方面做某事的成本。

相比之下,数学通常是声明性的(但是写一个证明往往更强命令式)。在数学中,你更关心正确性和定义不变的关系/操作,而不是你能多快得到答案。

请注意,许多函数式语言本质上都是声明性的(例如R,Lisp)。

z = x + y是什么意思? (语义)

命令式语言中,它意味着从内存位置x和y读取,将这些值一起添加,并将结果放入内存位置z,并立即执行。如果为x指定了不同的值,则必须再次使用z = x + y语句重新计算z。

声明性(懒惰)语言中,它表示z是一个变量,其值是另外两个变量x和y的值的总和。在您尝试读取z的值之前,不会执行加法运算。这意味着什么?如果从z读取,则该值始终为该时刻的x和y之和;你不需要重新发表声明。在没有变量的纯声明性语言中,重新发行实际上可以被捕获为错误!!!

记住这个例子,你会发现为什么数学家倾向于选择声明性语言。例如,我可以定义hypotenuse = sqrt(height ^ 2 + length ^ 2),从不担心必须重新发出该语句。这种关系是一种永远存在的不变量,就像数学真理一直存在一样。

在现实生活中(我为什么要关心?)

声明性语言的支持者声称:错误(错误)的有效解决方案是无用的。他们希望无错误的无状态函数没有副作用,无需修改就可以重复使用。

命令式语言的支持者声称:一个需要永久运行的正确解决方案也是无用的。他们希望控制内存/速度权衡。他们希望能够根据物理和时间限制进行​​优化。

当然,没有什么是100%强制性或声明性的。 命令式代码正确且写得很好意味着某些关系。 OTOH,声明性代码,足够深入并与语言规范结合,可以很好地描述这些关系,使编译器/解释器能够将您的代码转换为一系列CPU指令。

因为我们正在处理计算机,所以声明性编译器/解释器必须足够智能以进行时间与内存权衡,而在命令式语言中,程序员需要更多地做出这些决策明确。

因此,声明性语言要求程序员专注于定义变量和其他不变量之间的关系。编译器/解释器可以将这些关系转换为CPU的一系列指令/操作。大多数声明性编译器/解释器都足够智能,可以处理大多数真实案例,但可能会遇到边缘情况。不幸的是,在这些情况下,你必须哄骗编译器/解释器。

哪一个更好?

声明性语言的支持者声称,此类语言允许程序员专注于域并编写更容易为非程序员阅读的代码。声称倡导者,更容易编写正确的代码。然而,权衡是,哄骗编译器/解释器使正确的内存与速度权衡可能需要一些复杂的语言知识。如果使用R或SQL或LISP等声明性语言,您将理解此问题。当然可以定义一种与计算机无关的新声明性语言(但这样做可能会使解释器/编译器的编写者更难)。许多数学家和纯粹的CS研究人员喜欢声明性语言。

势在必行的语言往往会让您对机器进行更精细的控制。毫无疑问,您正在编程计算机。陷阱是,我们最终可能会过早地专注于不必要的速度优化,这会影响代码维护和可读性。在计算速度或内存严重受限的早期计算中,您需要使用命令式语言来完成有用的工作,并根据您的具体情况进行正确优化。工程师和修补工人倾向于使用命令式语言。

答案 2 :(得分:4)

C是一种必要的语言。

命令式语言指定 如何执行您想要的操作。声明性语言指定您想要的,但不指定如何执行;语言解决了如何做到这一点。 Prolog是一种声明性语言的例子。

答案 3 :(得分:1)

- &GT;命令式编程:告诉“机器”如何做某事,结果你想要发生什么。

- &GT;声明性编程:告诉“机器”你想要发生什么,让计算机弄清楚如何去做。

所以我们可以说C是一种必要的语言。

答案 4 :(得分:1)

我想评论一下C语言的某些方面,如果没有明确的规则,就会声明......

int i = 4;
int j = 5;

float f = i/j;

似乎意味着你打算浮动为.80(并且在声明性语言中,它很可能是)...但是因为有很好定义的过程int / int使用整数除法求值为int(其中)在C是地板部门。)

这是明确定义的行为的一个方面,使C Imperative。

C层的秘密在哪里可以进行优化,只要它们有保证不改变程序的输出,这使得编译器具有一些声明性行为,其中声明是行为的输入C程序,但最终结果可以是与功能中的C程序匹配的任何内容

§5.1.2.3第10部分:

  

或者,实现可以执行各种优化   在每个翻译单元内,使得实际的语义会   仅在进行函数调用时才同意抽象语义   跨翻译单位边界。在这样的实现中,在   每个函数的时间和函数返回调用的地方   函数和被调用函数在不同的翻译单元中,   所有外部链接对象和所有对象的值   通过其中的指针访问将与摘要一致   语义。此外,在每个这样的功能输入时   被调用函数和所有对象的参数值   通过其中的指针访问将与摘要一致   语义。在这种类型的实现中,引用的对象   由信号函数激活的中断服务程序   需要明确规定易失性存储,以及其他   实施定义的限制。

以及下一部分的具体示例:

  

示例2执行片段

char c1, c2; /* ... */
c1 = c1 + c2; 
  

''整数促销''要求抽象机器推广   每个变量的值为int size然后添加   两个整数并截断总和。提供两个字符   可以在没有溢出的情况下完成,或者使用溢出包装进行静默   产生正确的结果,实际执行只需要产生   同样的结果,可能省略了促销活动。