"函数"和"过程"有什么区别?

261

一般来说,在编程语言中,我们都会听到 函数过程 的概念。然而,我刚刚发现我几乎将这些术语互换使用(可能是非常错误的)。

那么我的问题是:

就它们的功能、目的和用法而言,它们有什么区别?请举个例子。

如果能提供一个例子就更好了。


参见:https://dev59.com/xmkv5IYBdhLWcg3wvDNF - gerrit
6
我认为SICP(《计算机程序的构造和解释》)说得很对。函数只存在于数学中,它们代表了“是什么”知识。程序存在于编程语言(包括函数式语言)中,它们代表了“如何做”的知识。例如: 函数:sqrt(x) = y,其中y满足y^2=x。程序(define (sqrt x) (newtons-method (lambda (y) (- (square y) x)) 1.0)) - mk12
3
我猜SICP是计算机程序的构造和解释这本书的缩写。 - jmrah
18个回答

3
在存储过程中,我们可以使用DML(插入/更新/删除)语句,但在函数中我们不能使用DML语句。
存储过程可以有输入/输出参数,但函数只能有输入参数。
我们可以在存储过程中使用Try-Catch块,但在函数中我们不能使用Try-Catch块。
我们不能在Select语句中使用存储过程,但在函数中我们可以在Select语句中使用。
存储过程可以返回0或n个值(最多1024个),但函数只能返回一个必需的值。
不能从函数中调用存储过程,但我们可以从存储过程中调用函数。
我们可以在存储过程中使用事务,但在函数中我们不能使用事务。
我们无法在任何地方(Where/Having/select部分)中使用存储过程作为Sql语句,但是我们可以在函数中使用。
我们无法连接存储过程,但我们可以连接函数。
欲知更多,请点击此处

2
这个答案非常依赖于具体的编程语言,而问题本身并不涉及特定的编程语言。这里的陈述在一般情况下并不全都正确,但是如果你能澄清一下你所指定的语言或环境,这会很有帮助。 - Mogsdad
这个答案对于绝大多数编程语言来说是完全错误的。过程只有输入参数,而函数既有输入又有输出。 - AStopher

2

一个函数会返回一个值,而一个过程只会执行命令。

“函数”这个名称源于数学,在输入的基础上计算出一个值。

过程是一组可按顺序执行的命令。

在大多数编程语言中,即使函数也可以有一组命令。因此,二者的区别在于是否返回一个值。

但如果您希望保持函数的简洁性(只需看看函数式语言),您需要确保函数没有副作用。


2

函数可以在SQL语句中使用,而存储过程不能在SQL语句中使用。

插入、更新和创建语句不能包含在函数中,但是存储过程可以有这些语句。

存储过程支持事务,但是函数不支持事务。

函数必须返回一个且仅一个值(另一个可以通过OUT变量返回),但是存储过程返回多个数据集和返回值。

函数和存储过程的执行计划都被缓存,因此两种情况下的性能相同。


1
在C#/Java中,函数是一段代码块,它返回特定的值,而过程是一段返回void(没有)的代码块。在C#/Java中,函数和过程通常被称为方法
    //This is a function
    public DateTime GetCurrentDate()
    {
        return DateTime.Now.Date;
    }

    //This is a procedure(always return void)
    public void LogMessage()
    {
        Console.WriteLine("Just an example message.");
    }

1
我反对在大多数答案中一再出现的观点,即使一个函数返回一个值,就能将其称为函数。实际上,为了成为真正的函数,方法必须在给定特定输入时始终返回相同的值。例如,在大多数语言中的 random 方法就不是函数,因为它返回的值并非始终相同。因此,函数更类似于映射(例如,对于一维函数,其中 x -> x')。这是常规方法和函数之间非常重要的区别,因为处理真正的函数时,计算的时间和顺序不应该有影响,而非函数则不总是如此。以下是另一个例子,它不是函数,但仍将返回一个值。
// The following is pseudo code:
g(x) = {
  if (morning()) {
     g = 2 * x;
  }
  else {
   g = x;
  }
  return g;
}

我进一步反对程序不返回值的观念。过程只是描述函数或方法的特定方式。这意味着,如果你的过程定义或实现的底层方法返回一个值,那么这个过程也会返回一个值。例如,看看SICP中以下代码片段:
// We can immediately translate this definition into a recursive procedure 
// for computing Fibonacci numbers:

(define (fib n)
  (cond ((= n 0) 0)
        ((= n 1) 1)
        (else (+ (fib (- n 1))
                 (fib (- n 2))))))

你最近听说过递归程序吗?他们在谈论一个递归函数(一个真正的函数),它返回一个值,他们使用了“过程”这个词。那么区别是什么呢?

除了上面提到的意义之外,将函数看作理想化表示(例如数字1)的另一种方式是将过程视为该事物的实际实现。我个人认为它们是可以互换的。

(请注意,如果您阅读我提供的链接中的章节,您可能会发现更难掌握的概念不是函数和过程之间的区别,而是进程和过程之间的区别。您知道递归过程可以有迭代过程吗?)

过程的类比是食谱。例如,假设您有一台名为make-pies的机器,该机器接收(水果、牛奶、面粉、鸡蛋、糖、热量)等成分,然后返回一个馅饼

该机器的表示可能如下:

make-pies (fruit, milk, flower, eggs, sugar, heat) = {
   return (heat (add fruit (mix eggs flower milk)))
}

当然,这并不是制作馅饼的唯一方法。
在这种情况下,我们可以看到:
A       function     is to a     machine
as a    procedure    is to a     recipe
as      attributes   are to      ingredients
as      output       is to       product

这个类比还可以,但是当你考虑到当你处理计算机程序时,一切都是抽象的。因此,与向机器提供食谱的情况不同,我们正在比较两个本身就是抽象的东西;两个几乎可以视为同一件事情。我认为它们(在所有意图和目的上)是相同的。


2
一个总是为给定参数返回相同值的函数有时被称为“纯函数”。在大多数区分过程和函数的语言中,函数不需要是纯的,并且术语“函数”正确地用于指称可以具有副作用并且可以在连续调用相同参数时返回不同结果的子例程。(在类似C的语言中,甚至不返回值的子例程也被称为“函数”。) - Keith Thompson
同意,这就是为什么我最后说这些词是可以互换的原因。 - dkinzer
1
是的,但你首先要说“函数不仅仅是返回值的任何旧方法”,而在许多语言中,这正是函数的定义。 - Keith Thompson

0
在数据库(db)的上下文中: 存储过程是预编译的执行计划,而函数则不是。

-3

过程: 1.过程是定义参数化计算的语句集合。 2.过程无法返回值。

3.函数无法从函数中调用。

函数: 1.函数在结构上类似于过程,但在语义上建模于数学函数。 2.它可以返回值。 3.过程可以从函数中调用。


“3. Procedures cannot be called from function.” 这是在哪种编程语言中成立的?在我所熟悉的语言中都没有这个限制。 - Mogsdad
这是真的。如果你从一个函数中调用一个过程,那么它就不是一个函数了。至于哪种语言强制执行这一点,这是一个很好的问题,我不知道答案。可能是函数式语言,但即使如此,我也不确定:纯列表是函数式的(没有集合:没有副作用),但由于它有lambda,所以可以实现set。你能写一个编译器来强制禁止使用set吗?它必须检测到所有的实现。你可以从语言中删除lambda,但那会更糟。 - ctrl-alt-delor
哦,我刚想到了一种语言C++:一个const方法不能调用一个非const方法(尽管你需要打开正确的编译器检查,并且不要试图绕过它)。 - ctrl-alt-delor

-10

过程和函数都是子程序,它们之间的唯一区别在于过程返回多个(或至少可以)值,而函数只能返回一个值(这就是为什么数学中使用函数符号,因为通常在给定时间只找到一个值),尽管一些编程语言不遵循这些规则,但这是它们真正的定义。


不,一个过程并不会“返回”任何东西。你说的是副作用,这在两种语言中都是可能的(如果语言允许)。 - Mogsdad
一个过程可以返回任意数量的值,这个数量可能是零。 - user2766296
一个副作用是,如果a有一个数组,并将其传递到一个函数或过程中,该函数或过程会找到最大值,则该数组将按引用传递,并且在子例程运行后,该数组将被排序,它被排序的事实是一个副作用,返回的值是数组中的最大值。 - user2766296
我喜欢这个答案,也喜欢那些有几个踩的,因为某种程度上它们是正确的,所以,矛盾地,为了让它在SO上非常受欢迎,我会给它一个踩。在SQL Server中,存储过程返回结果集(你所说的“多个值”),而函数只能返回一个值(这并不完全准确,因为你也可以创建一个表值函数)。 - user2188550

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接