【问题标题】:Do we still need subroutines? [closed]我们还需要子程序吗? [关闭]
【发布时间】:2010-10-15 11:21:45
【问题描述】:

在 Fortran 中,函数和子程序之间存在明显的区别:函数返回一个值,子程序不返回值。这会在两者之间引入一连串的差异。一个例子是调用语义:你可以像在其他语言中一样调用一个函数,但是为了调用一个子例程,你必须首先发出一个call 语句。

随着在 Fortran95 中添加指针和数据类型,使任何子程序成为函数并保留子例程仅用于遗留似乎没有技术限制。函数可以返回零(您只返回一个虚拟整数)、一个或多个值(例如,您可以返回一个指向已分配类型实例的指针,例如 C++ STL 对)。

我错了吗?由于子程序具有而函数没有的某些特性,我们在 Fortran 编程中还需要子程序吗?

【问题讨论】:

  • 不,我们没有;我们也不需要在具有 do while... 的语言中使用 do i=1.. 循环。
  • 我认为这个问题在programmers.stackexchange.com上会更好,因为它非常主观。
  • @David:阅读我对非主观问题的非主观回答。
  • 除非我大学后的记忆已经消失,否则 Pascal 拥有(或至少拥有)相同类型的函数和子例程。我认为 BASIC 的某些版本也做了/做了。在 C 之前学过这些(和 FORTRAN)后,我发现 C 中只有函数很奇怪!
  • 回想一下,fortran IV 和 fortran 77 至少是严格的引用调用语言。除非你想写p = q + estimate(r,s,t),否则根本不需要“返回”一个值,因为评估的副作用是当务之急。这些语言的直接后代将并且应该继续具有区别因为有后代。如果您不喜欢 fortran 的该功能,请不要使用 fortran。嘘。

标签: fortran fortran95


【解决方案1】:

如果您搜索 comp.lang.fortran 档案,您会发现有关函数语义的讨论。 IIRC 事实证明,标准中没有明确规定对于具有副作用的功能什么是允许的,什么是不允许的。

比如编译器能不能优化

x = foo(args) + foo(args)

进入

x = 2 * foo(args)

或者再举一个例子,考虑

x = y + foo(y)

如果 foo() 改变了 y 的值怎么办?请记住,Fortran 没有序列点的 C 概念。

一般来说,几位专家的建议是只使用纯函数,否则使用子例程。而且,这也是我自己遵循的建议。

【讨论】:

  • 我对你的支持不够。谢谢!
  • 而且由于你是唯一一个真正在技术上回答的人,所以我找到了你回答的一个问题,悬赏它,并在允许的情况下尽快奖励给你(因为我不能这样做这个问题了)。
【解决方案2】:

我不认为子程序会去任何地方。大多数其他语言都允许返回值和不返回值的方法。我看不出这是一件坏事的任何理由。任何人都不应该被感动去改变一件事。

Legacy 单独表示,子例程将与 Fortran 一样持续存在。只要有 Fortran 存在,编写一个执行操作但不返回任何内容的方法就没有任何问题。

更新:

为什么说“麻烦”?有什么大不了的?我不同意在适当的情况下使用子例程是“麻烦”的想法。

Fortran 自 77 版(可能更早)以来一直区分函数和子例程。其他 C 系列语言也是如此。为什么会突然变得这么麻烦?即使是长期使用指针和对象的语言也有返回 void 的方法。

【讨论】:

  • @Stefano Borini:没有人试图强迫您使用您不喜欢的 Fortran 功能。就个人而言,我怀疑我不是唯一有这种想法的 Fortran 程序员,我发现指针比值更改函数称为子例程更麻烦。
  • @Stefano - 最好停止使用所有这些“无用”语言编写代码。我可以调用在 Java、C、C++ 或 C# 中返回 void 的方法。我不觉得它没用。我已经投票结束这个。这不是一个真正的问题,主观的和争论的。
  • @Stefano,我给了你一个技术答案。你没有承认或接受它。
  • 这种区别早于 FORTRAN 77。我不知道它可以追溯到多长时间,但在我使用时它在 FORTRAN 66 中看起来并不新鲜。
  • 你没有;我不能引用它。您询问是否仍需要子例程。我说他们是,而且永远都是。如果您想停止使用它们,欢迎您这样做。其他选择不同的人不太可能跟随你的领导或关心你的论点。我不明白这是从哪里开始的。我知道我没有别的东西可以提供。我们会看看是否还有其他人这样做。
【解决方案3】:

你又想用 fortran 编写 C 语言了,是吗? ;-)

在我看来,是的 - 我们这样做。如果仅出于一个原因 - 它们更容易掌握,理解,并且它们比函数更广泛使用。

另外,-1,因为我认为这不是一个建设性的问题。如果您不喜欢它们,请不要使用它们。

【讨论】:

  • 给我一个像我必须找到自己的答案,这是我需要的答案怎么样?
  • @Stefano - 你的问题是我们是否需要它们,我陈述了我的意见。那你还想要什么?如果您想花时间尝试规避子程序的正常使用,请成为我的客人。之后,您可以尝试找到其他方法来处理其他事情。那就是通往天堂的道路,就是这样。然而,它是非建设性的,因为 99% 的人仍然认为它们有用,并且不梦想将它们扔掉(实际上,即使他们希望它们不能——fortran 标准要求它)。没有任何有用的结果可以导致回答这个问题,因此我的 -1。
  • 告诉我,扔掉它们有什么实际用途? (伙计,这让我想起了那些大写锁定问题)。
  • @Stefano - 好吧,这是他们的问题,不是吗?不,这里的 fortran 社区很好(有点小,但其他方面很可靠),但重点是,我强调的是,python(或其他一些......)非常适合搞乱,玩弄等等,而fortran不是。它是一个语言。这只是做它应该做的。我的意思是,我并不是要抨击你,但你的问题有时确实看起来有点小题大做。例如,我想不出除了一些乱七八糟的技巧之外,在这种情况下,什么答案会让你满意,而且像往常一样,这些问题最终会在 cmets 中引发激烈的争吵。
  • “F77 没有类型”???? “类型”对你和我来说意味着什么不同的东西吗?因为fortan 77当然支持integerreal*8complexchar(255)等等。
【解决方案4】:

如果我理解正确的话,Stefano 并不反对子程序的想法。反对他们的意见是无稽之谈。他反对对子程序/函数使用不同的风格。

Fortran 是命令式编程语言。更准确地说,它是一种过程编程语言(更准确地说,它是结构化编程语言)。

在命令式编程中,我们有一个状态和语句来改变它。在过程编程中,我们进行更改的工具是过程(我们在过程中本地化更改)。该过程可能会或可能不会返回一些值。而且我不认为这个事实(过程返回值与否)是在编程语言中有两个不同实体的重要原因。我们可以只有函数(就像在 C 中一样),并且在我们实际上不需要返回某些东西(void)时只返回一些特殊的东西。或者我们可以只使用允许返回值的过程和特殊语法,如 Modula-2、Oberon、...

该语言可能应该只有一种风格来声明过程。我同意你的看法,Stefano。

【讨论】:

  • 我的问题是关于潜在差异的更多相关性,我不知道它授予子程序一些函数中不允许的特殊功能。我会修改这个问题,因为它显然不够清楚。
  • "该语言可能应该只有一种风格来声明过程。" - 你为什么相信?如果 Fortran 很早就有子例程和函数,而指针只是最近添加的,它与 C 等语言中的子例程和函数共存,那么只有一种过程风格的理由是什么? Fortran 不是 Haskell。
  • @dyffymo:我并不是说我们只需要函数(有返回值)而不需要子例程(没有返回值)。最后一个很有用。例如,用于逐步程序组合。我唯一喜欢的是声明函数和子例程的统一语法(如 Modula-2 及其后代中的过程声明)。我不相信,但就是喜欢它。
【解决方案5】:

我必须回答自己这个问题的事实是疯狂的,但事实就是如此。

区别在于您不能在 Fortran 中“像其他语言一样调用函数”。而在 C 中,您可以在不分配值的情况下调用整数函数,例如

int foo() {
    return 5;
}
int main() {
    foo(); // this works
}

在 Fortran 中,您始终必须关联一个接收变量。示例

module test
   implicit none

contains
   integer function foo()
      print *, "hello"
      foo = 0
   end function

end module

program hello
   use test
   integer :: x

   x = foo() ! this works
   foo() ! this does not compile

end program hello

意味着通过返回一个虚拟整数来“模拟”一个 void 函数仍然不允许您在没有接收器变量的情况下调用。

在 Fortran 中,void 返回类型不存在。从技术上讲,你可以用所有函数来构建你的程序,用上面看到的x = 替换每次出现的call 语句,但这不会使你的语法类似于 C 或其他语言,其中没有 void 之间的区别-返回函数和非空返回函数。子例程是唯一允许“返回 void”的实体,但执行调用的语义完全不同。除此之外,两者没有区别。

【讨论】:

  • @Stefano Borini:所以我在工作日结束时回到了这个问题。我看到它像大多数类似“为什么语言 X(不)具有特征 Y?”的问题一样,产生了没有任何意义的声音和愤怒。在这里的 cmets 之间,我花了一天时间编写 Fortran 来解决计算 EM 问题,无论是忽略还是不知道,您正在为之着迷的语言设计的更好点。如果 Fortran 2008 具有过去遗留下来的功能,而今天设计的语言中没有人会包含这些功能,我真的不会打扰。
  • “计算 EM” - 现在值得一听。 HPM,我很想知道更多关于你是如何做到的。有限元?还有什么?是否涉及多物理场? (例如,感应加热)。
  • @High:好的,所以你是一个坏蛋编码员。现在呢?
  • @Stefano Borini:现在是周五 17:05(当地坐标),我去酒吧。祝您周末愉快。
  • “我必须回答自己的事实” 表明你被锁定在一种思维方式中,并且不接受其他人可能会有不同的感觉。如果您说 StefBortran 不会有这种行为,那很好:对您有好处。 Fortran 有它因为 fortran 有它。故事结局。其他一切都是茶叶阅读。
猜你喜欢
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
  • 2020-08-22
  • 1970-01-01
  • 2011-11-14
  • 2019-08-26
  • 1970-01-01
相关资源
最近更新 更多