试着想这么一个程序,在一个程序中输出5的三次方,6的四次方和7的五次方。可能有人想到这样的写法:
#!/usr/bin/tclsh
puts [expr 5*5*5]
puts [expr 6*6*6*6]
puts [expr 7*7*7*7*7]
不得不承认这是一个好的办法,代码行数少,简单易懂,可是如果我告诉你要输出2的30次方和3的15次方呢?
是不是可以继续2*2*2…*2呢?当然可以,可是这样是不是已经很麻烦了?
于是有人想到了以前学习的循环,于是会用这样的程序
#!/usr/bin/tclsh
set result1 1
for {set i 0} {$i<30} {incr i} {
set result1 [expr $result1*2]
}
puts $result1
set result2 1
for {set j 0} {$j<15} {incr j} {
set result2 [expr $result2*3]
}
puts $result2
很不错,前面学习的知识已经用到了,但是你是不是觉得有点别扭呢?程序分成了两段,几乎都是一抹一样的,是不是有更好的办法呢?对的,可以通过过程来实现,如果学过其他语言,过程也被叫做函数。
其表现形式为
Proc procname {var1 var2 … } {
program
}
其中var1,var2等在过程中的参数,被称为形式参数,简称形参而在程序中调用proc的时候,写在var1和var2位置的参数,被称为实际参数,简称实参。
下面看看上一个程序用过程来实现
#!/usr/bin/tclsh
# Procedure
proc calvalue {var1 var2} {
set result1 1
for {set i 0} {$i<$var2} {incr i} {
set result1 [expr $result1*$var1]
}
return $result1
}
puts [calvalue 2 30]
puts [calvalue 3 15]
如何?是不是看起来也很简单和清楚呢?
当然,你也可以直接在过程中就输出结果,如下面的这个样子:
#!/usr/bin/tclsh
# Procedure
proc calvalue {var1 var2} {
set result1 1
for {set i 0} {$i<$var2} {incr i} {
set result1 [expr $result1*$var1]
}
puts $result1
}
calvalue 2 30
calvalue 3 15
但是考虑到过程的返回值会被其他的地方用法,所以我建议使用第一种return value的模式。
既然有了过程,那么就会有人产生疑问了,我在过程里面变量的值,在过程外面能不能使用呢?或者在过程外面变量的值,过程里面能不能用呢?
那么,先看一个程序吧:
#!/usr/bin/tclsh
proc test1 {} {
set var1 3
}
puts $var1
执行结果呢?
can't read "var1": no such variable
while executing
"puts $var1"
而如果是过程中和过程外都对变量进行了定义,看程序:
#!/usr/bin/tclsh
set var1 5
proc test1 {} {
set var1 3
puts $var1
}
test1
puts $var1
其运行结果
3
5
很明显,在默认的情况下,主程序是不能读取过程中的变量的,如果子程序中没有定义变量,直接使用就会出错,如果子程序中单独定义了,则是子程序自己定义的值。那么有没有办法呢?答案是有的。
如果要获得过程中的变量值,有两种方法,一个是前面大家看到的return,另外一种就是使用global定义变量为全局变量,看程序:
#!/usr/bin/tclsh
set var1 5
proc test1 {} {
global var1
puts $var1
set var1 3
}
test1
puts $var1
其运行结果是:
5
3
可以看出来,在过程中输出的时候,变量值为主程序中的5,然后在过程中改变了变量的值为3,在主程序中输出,值变为了3。