函数和子程序有什么区别?

时间:2011-05-18 17:01:30

标签: terminology

函数和子例程有什么区别?有人告诉我,函数和子程序之间的区别如下:

函数接受参数,在本地工作,不会改变任何值或使用其范围之外的任何值(高内聚)。它还返回一些值。子程序直接与调用它的调用者或代码段的值一起工作,并且不返回值(低内聚),即将一些代码分支到某些其他代码以便进行一些处理并返回。

这是真的吗?或者没有区别,只有两个术语来表示一个?

12 个答案:

答案 0 :(得分:9)

我不同意。如果通过引用传递参数到函数,则可以在函数范围之外修改该值。此外,函数不必返回值。考虑C中的void some_func()。因此OP中的前提是无效的。

在我看来, function 子例程之间的区别是语义。也就是说有些语言使用不同的术语。

答案 1 :(得分:8)

函数返回值,而子例程则不返回。函数不应该改变实际参数的值,而子例程可以改变它们。

这就是我对它们的定义; - )

答案 2 :(得分:8)

如果我们用C,C ++,Java和其他相关的高级语言进行交流:

一个。子例程是用于编写算法(或流程图)以在一个地方指定处理功能的逻辑构造。子程序根据输入提供一些输出,其中处理可能保持不变。

湾函数是编程语言

中子程序概念的实现

答案 3 :(得分:4)

就Visual Basic而言,子例程是一组执行定义明确的任务的指令。说明放在SubEnd Sub语句中。

函数类似于子例程,但函数返回一个值。子例程执行任务但不向调用程序报告任何内容。函数通常执行一些计算并将结果报告给调用者。

答案 4 :(得分:3)

函数和子程序都返回一个值,但是当函数无法在OUT路径上改变IN的参数值时,子程序可以。此外,您需要为传出值定义变量名称,而对于函数,您只需要定义输入变量。例如,函数:

double multi(double x, double y) 
{
  double result; 
  result = x*y; 
  return(result)
}

只有输入参数,并且不需要返回值的输出变量。另一方面,通过子程序完成的相同操作将如下所示:

double mult(double x, double y, double result) 
{
  result = x*y; 
  x=20; 
  y = 2; 
  return()
}

这与函数的作用相同,即返回x和y的乘积,但在这种情况下,您需要将结果定义为变量,(2)您可以更改x的值和在回来的路上。

答案 5 :(得分:1)

其中一个差异可能来自术语来源。

子程序更多的是计算机体系结构/组织术语,这意味着执行一项任务的可重复使用的指令组。它存储在内存中一次,但必要时经常使用。

函数起源于数学函数,其基本思想是将一组输入映射到一组允许的输出,其属性是每个输入只与一个输出相关。

答案 6 :(得分:0)

我正在从VBA的excel角度写这个答案。如果您正在编写函数,那么您可以将其用作表达式i。即你可以从excel的任何单元格中调用它。

例如:excel中的普通vlookup函数无法查找值> 256个字符。所以我使用了这个功能:

Function MyVlookup(Lval As Range, c As Range, oset As Long) As Variant
  Dim cl As Range
  For Each cl In c.Columns(1).Cells
  If UCase(Lval) = UCase(cl) Then
  MyVlookup = cl.Offset(, oset - 1)
  Exit Function
  End If
  Next
End Function

这不是我的代码。从另一个互联网帖子得到它。它工作正常。

但真正的优势是我现在可以从excel中的任何单元格中调用它。如果写了一个子程序,我就不能这样做。

答案 7 :(得分:0)

基于Wikipedia subroutine定义:

  

在计算机编程中,子例程是程序序列   打包成一个单元执行特定任务的指令。这个   然后,该单元可以在程序中使用该特定任务   被执行。

     

子例程可以在程序中定义,也可以在库中单独定义   可以被许多程序使用。用不同的编程语言   子例程可以称为过程,函数,例程,   方法或子程序。通用术语可调用单位有时是   使用。

在Python中,子例程和函数之间没有区别。 在VB / VB.NET中,函数可以返回一些结果/数据,而子例程/子不能。 在C#中,子例程和函数都引用了一种方法。

有时在OOP中,属于该类的函数称为方法。

由于高级语言抽象了这种差异,因此不再需要区分函数,子例程和过程,因此最后,这两者之间的语义差异很小。

答案 8 :(得分:0)

是的,它们与您所说的不同。

一个函数具有确定的输出并且没有副作用。
子例程没有这些限制。

函数的经典示例是int multiply(int a, int b)
它是确定性的,因为乘法(2,3)总是会给你6。
它没有副作用,因为它不会修改范围以外的任何值,包括a和b的值。

子例程的示例是void consume(Food sandwich)
它没有输出,因此不是函数。
它具有副作用,因为调用此代码将消耗三明治,并且您不能再在同一三明治上调用任何操作。

您可以将函数视为f(x)= y,或者对于乘法,f(a,b)= c。是的,这是编程而不是数学。但是要使用数学模型和乞求。所以我们在CS中使用数学。如果您想知道为什么要区分函数和子例程,则应查阅函数编程。就像魔术一样。

答案 9 :(得分:0)

从用户的角度来看,编程功能和子例程之间没有区别,但是从理论上讲,绝对有区别!

子程序和函数之间的概念本身是不同的。在形式上,OP的定义是正确的。子例程不接受参数,也不通过 formal 语义给出返回值。这只是对约定的一种解释。子例程中的变量可以在同一文件的其他子例程中访问,尽管在C语言中也可以实现,但是有些困难。

摘要:

从您使用的编程语言的角度来看,子例程仅基于副作用起作用。概念本身没有明确的参数或返回值。您必须使用副作用来模拟它们。

函数是从某种意义上说是输入到输出值的映射,是某种通用的替换操作。从编程世界的角度来看,函数是子例程的抽象,其子例程受数学函数的启发,包含有关返回值和参数的信息。附加的形式化抽象将功能与编程上下文中的子例程区分开。

详细信息:

该子例程最初只是一个可重复的代码段,您可以在其他代码之间调用。它起源于汇编或机器语言编程,并指定指令序列本身。鉴于此含义,Perl还将术语子例程用于其可调用的代码片段。

子例程是具体对象。

这就是我的理解:(纯)函数的概念是一个数学概念,是具有自己的形式符号的数学关系的特例。您有一个输入或自变量,并且定义了具有给定自变量的函数表示的值。原始功能概念与指令或计算完全无关。数学运算(或编程世界中的指令)只是实际映射的流行形式表示(描述)。原始功能项本身未定义为代码。计算不构成函数,因此函数实际上没有任何计算开销,因为它们是直接映射。功能复杂性方面的考虑只是在找到映射的开销时才出现。

函数是抽象对象。

现在,由于整个PC材料都在小型机器指令上运行,因此建模(或实例化)数学的最简单方法是使用一系列指令本身。计算机科学是由数学家(值得注意的是:Alan Turing)建立的,第一个编程概念是基于它的,因此有必要将数学引入机器。这就是我想像的原因,为什么“功能”是作为子例程实现的事物的名称,以及为什么创造“纯”功能这一术语是为了将原始功能概念与编程语言中过分的术语区别开来。

注意:在汇编语言编程中,通常会说子例程已传递参数并给出返回值。这是在具体形式语义之上的解释。调用约定指定在调用子例程或返回之前应将值(应视为参数和返回值)写入的位置。调用本身仅使用一个子例程地址,并且没有形式参数或返回值。

编程语言中的

PS:函数不一定必须是子例程(即使以这种方式开发的编程语言术语也是如此)。功能编程语言中的函数可以是常量变量,数组或哈希表。 ECMAScript中的每个数据结构不是一个函数吗?

答案 10 :(得分:0)

区别在于隔离。子程序只是程序的一部分,以标签开始并以转到结束。函数位于程序其余部分的命名空间之外。它就像一个单独的程序,可以具有与调用程序中使用的相同变量名,并且无论它对它们做什么都不会影响调用程序中具有相同名称的那些变量的状态。

从编码的角度来看,隔离意味着您不必使用函数本地的变量名称。

副双:

a = a + a

Return

fnDouble(随便):

whatever = whatever + whatever

Return whatever

该子程序仅适用于 a。如果你想加倍 b 你必须在调用子程序之前设置 a = b 。然后您可能需要在之后将 a 设置为 null 或零。然后,当您想将 c 加倍时,您必须再次将 a 设置为等于 c。 此外,sub 中可能还有一些其他变量 z,当 sub 跳转到时会更改该变量,这有点危险。

关键是将名称与函数隔离(除非在函数中声明为全局。)

答案 11 :(得分:-1)

每个子程序执行一些特定任务。对于某些子例程,该任务是计算或检索某些数据值。这种子程序称为函数。我们说函数返回一个值。通常,返回的值意味着在调用函数的程序中以某种方式使用。

相关问题