zoukankan      html  css  js  c++  java
  • tcl/tk过程

    过程基础:
    过程由 proc 命令创建,格式如下:
    proc 过程名 参数列表 过程体
    实例如下:
    proc plus {a b} {expr {$a + $b}}
    plus命令的返回值就是它的过程块中最有一个命令的返回值。
    可以用return提前返回, return 的参数就是该过程的返回值。下面是使用return命令的阶乘功能实现:
    proc fac {x} {
     if {$x <= 1} {
      return 1;
     }
     return [ expr {$x * [fac [expr {$x - 1}]]}]
    }
    fac 4
    =>24
    fac 0
    =>1

    局部和全局变量:
    过程可以使用 global 命令引用全局变量。例如,下面这条命令让全局变量x y在过程中可见
    global x y
    global命令把它的每一个参数作为全局变量的名称对待,将过程中对这些变量名的引用定向到全局变量而非局部变量。
    global命令可以在过程中的任何时候调用;一旦调用,它就会一直有效,知道过程返回。

    参数个数和默认值设置:
    过程可以有0个参数,只需要参数列表为 {} 即可:
    proc printVars {} {
      puts "a is $a,b is $b"
    }

    设置参数默认值:
    proc inc {value {increment 1}} {
     expr $value+$increment 
    }
    该过程有两个参数,一个固定参数value,一个可选参数increment,默认值是1。
    可选参数在调用时可以不必给出。
    inc 42 3
    =>45
    inc 42
    =>43
    默认参数必须放在参数列表的尾部。如果一个参数是默认参数,那么参数列表中它后面的参数都必须是默认参数。

    特殊参数 args ;
    如果参数列表中最后一个参数是特殊名称args,那么可以给出可变数量个参数。
    例如下面这个过程,获取任意个参数,返回它们的和:
    proc sum {base args} {
     set total 0
      foreach val $args {
      set total [ expr {$total + $val}]
     }
     return [expr {$base + $total}]
    }
    其中base参数必须给出。使用如下:
    sum 1
    =>1
    sum 1 2
    =>3
    sum 1 2 3
    =>6
    sum 
    =>wrong # args: should be "sum base ?arg ...?"
    提示错误,base参数未指定。

    传引用调用upvar:
    可以用 upvar 命令模拟传引用调用的行为,这对数组特别有用。如果a是一个数组,就不能像myproc $a这样把它传给过程myproc,因为并没有
    对应整个数组的值;只有对应各个数组元素的值。
    但是可以把数组名传给过程,myproc a,然后使用upvar命令在过程中访问数组的元素。
    下面是在过程中使用upvar的简单示例,输出一个数组的内容:
    proc printArray {name} {
     upvar $name a
     foreach el [ lsort [ array names a]] {
      puts "$el=$a($el)"
     }
    }

    set info(age) 37
    set info(position) "vice president"
    printArray info
    =>age=37
      position=vice president
     
    上述代码中upvar命令使得过程可以通过变量a访问这个数组。

    应用匿名过程:
    apply 
    {argList body ?namespace?} ?arg1 arg2 arg3 ...?
    argList是过程的形参,body是实现过程块的tcl脚本,?namespace?是可选的,指明运行过程的命名空间。
    ?arg1 arg2 arg3 ...?是赋给过程参数的值。
    下面这个匿名过程对一下数求和:
    apply {{args} {
     set total 0
     foreach val $args {
      set total [expr {$total + $val}]
     }
     return $total
    }} 1 2 3 4 5 6 7
    =>28
    它把1 2 3 4 5 6 7作为一个列表传给过程的形参args,然后匿名过程计算并返回这些值的和。

    一个更有代表性的例子,考虑对一个列表依据各个元素的字符串长度排序。lsort命令的-command选项可以指定自己的排序过程。
    set states {333 22 4444 1}
    lsort -command {apply {{e1 e2} {
                                 expr {[ string length $e1] - [string length $e2]}
                                }
                          }
                        } $states
    =>1 22 333 4444            

    apply 可以用于创建实现不同功能的结构块。下面的代码展示了map命令的实现。
    proc map {lambda list} {
     set result {}
     foreach el $list {
      lappend result [apply $lambda $el]
     }
     return $result
    }       
     map {x {expr {$x*$x}}} {1 2 3 4}
     =>1 4 9 16
     map {x {return [ list [string length $x] $x]}} {a bb ccc dddd}
     =>{1 a} {2 bb} {3 ccc} {4 dddd}

  • 相关阅读:
    Beyond Compare工具栏操作按钮可以增加吗
    Beyond Compare同步压缩文件夹的步骤
    Beyond Compare和UltraCompare有什么不一样
    Beyond Compare表格比较该怎么控制行对齐
    Beyond Compare的这些使用技巧你喜欢吗
    设置Beyond Compare比较文件显示样式的方法
    图片比较有了它就可以了
    关于容斥做题随记
    Heron and His Triangle HDU
    No more tricks, Mr Nanguo HDU
  • 原文地址:https://www.cnblogs.com/kane1990/p/2293981.html
Copyright © 2011-2022 走看看