【问题标题】:Recursive TCL proc without explicit return没有显式返回的递归 TCL proc
【发布时间】:2019-07-17 19:14:15
【问题描述】:

我正在编写一个简单的“proc”来计算阶乘。我想了解为什么我的函数在没有 return 语句的情况下不起作用。

根据 TCL 文档,没有明确“返回”定义的函数, 返回其主体中最后执行的命令的值。

    proc fac { n } {
       if { $n == 1 } {
         return 1
       } 
    puts $n
    set n [expr {$n - 1}]
    return [expr {[fac $n ] * $n}]                                                                                                                                                            
    }
    puts [fac 5] # ans 24

当“return”被删除时,我收到以下错误消息:

    invalid command name "1"
      while executing
     "[expr {[fac $n ] * $n}] "
        (procedure "fac" line 7)
        invoked from within

我预计如果没有明确的“返回”,该函数也应该返回 24。

【问题讨论】:

  • 你为什么认为5! == 24
  • 这不能回答你的问题,但可以这样实现:proc ::tcl::mathfunc::fac {n} { expr {$n == 1 ? 1 : $n * fac($n - 1)} } 然后expr {fac(6)}
  • 您的 proc 在 Tcl 8.5 或 8.6 上没有返回任何错误...只是您计算阶乘的方式不正确。

标签: recursion tcl


【解决方案1】:

你的预期是正确的。但是你在最后一行的expr 过程中有方括号。它是:

[expr {[fac $n] * $n}]

这对解释器来说意味着: 1) 使用给定的参数执行expr 过程; 2) 执行expr 过程的结果。因此,解释器尝试执行不存在的过程1,您会收到错误消息。

要修复此错误 - 只需从最后一行删除方括号:

proc fac { n } {
   if { $n == 1 } {
     return 1
   } 
   puts $n
   set n [expr {$n - 1}]
   expr {[fac $n ] * $n}                                                                                                                                                           
}

【讨论】:

  • 感谢您的回答。但是,我不清楚为什么它与“return”一起使用。为什么在这种情况下解释器不会再次尝试执行 [1]?
  • 解释器使用第一个单词作为命令的名称。 Return 是一个接受参数的命令,其中一个参数可以是您希望作为过程值返回的值。在您的情况下,您给出的参数是执行 expr 命令的返回值。 expr 命令、它的参数和括起来的括号被替换为 expr 命令本身的执行结果。如果没有任何明确的返回命令,程序将返回最后执行的命令的值。这就是朴素的 expr 命令起作用的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-30
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-12
  • 2018-07-22
相关资源
最近更新 更多