23.2. 局部变量
优质
小牛编辑
131浏览
2023-12-01
怎么样使一个变量变成局部的?
- 局部变量
如果变量用local来声明,那么它只能在该变量声明的代码块(block of code)中可见. 这个代码块就是局部"范围". 在一个函数内,局部变量意味着只能在函数代码块内它才有意义.
例子 23-12. 局部变量的可见范围
1 #!/bin/bash 2 # 在函数内部的全局和局部变量. 3 4 func () 5 { 6 local loc_var=23 # 声明为局部变量. 7 echo # 使用内建的'local'关键字. 8 echo "\"loc_var\" in function = $loc_var" 9 global_var=999 # 没有声明为局部变量. 10 # 默认为全局变量. 11 echo "\"global_var\" in function = $global_var" 12 } 13 14 func 15 16 # 现在,来看看是否局部变量"loc_var"能否在函数外面可见. 17 18 echo 19 echo "\"loc_var\" outside function = $loc_var" 20 # $loc_var outside function = 21 # 不, $loc_var不是全局可访问的. 22 echo "\"global_var\" outside function = $global_var" 23 # $global_var outside function = 999 24 # $global_var 是全局可访问的. 25 echo 26 27 exit 0 28 # 与In contrast to C相比, 在函数内声明的Bash变量只有在 29 #+ 它被明确声明成局部的变量时才是局部的.
在函数调用之前,所有在函数内声明且没有明确声明为local的变量都可在函数体外可见.
1 #!/bin/bash 2 3 func () 4 { 5 global_var=37 # 在函数还没有被调用前 6 #+ 变量只在函数内可见. 7 } # 函数结束 8 9 echo "global_var = $global_var" # global_var = 10 # 函数"func"还没有被调用, 11 #+ 所以变量$global_var还不能被访问. 12 13 func 14 echo "global_var = $global_var" # global_var = 37 15 # 已经在函数调用时设置了值.
例子 23-13. 用局部变量来递归
1 #!/bin/bash 2 3 # 阶乘 4 # --------- 5 6 7 # bash允许递归吗? 8 # 嗯, 允许, 但是... 9 # 它太慢以致你难以忍受. 10 11 12 MAX_ARG=5 13 E_WRONG_ARGS=65 14 E_RANGE_ERR=66 15 16 17 if [ -z "$1" ] 18 then 19 echo "Usage: `basename $0` number" 20 exit $E_WRONG_ARGS 21 fi 22 23 if [ "$1" -gt $MAX_ARG ] 24 then 25 echo "Out of range (5 is maximum)." 26 # 现在让我们来了解实际情况. 27 # 如果你想求比这个更大的范围的阶乘, 28 #+ 应该重新用一个真正的编程语言来写. 29 exit $E_RANGE_ERR 30 fi 31 32 fact () 33 { 34 local number=$1 35 # 变量"number"必须声明为局部, 36 #+ 否则它不会工作. 37 if [ "$number" -eq 0 ] 38 then 39 factorial=1 # 0的阶乘为1. 40 else 41 let "decrnum = number - 1" 42 fact $decrnum # 递归调用(函数内部调用自己本身). 43 let "factorial = $number * $?" 44 fi 45 46 return $factorial 47 } 48 49 fact $1 50 echo "Factorial of $1 is $?." 51 52 exit 0
也请参考例子 A-16的脚本递归的例子. 必须意识到递归也意味着巨大的资源消耗和缓慢的运行,因此它不适合在脚本中使用.
注
Herbert Mayer给递归下的定义是". . . expressing an algorithm by using a simpler version of that same algorithm(用一个相同算法的版本来表示一个算法). . ."递归函数是调用它自己本身的函数.
太多层的递归可能会引起脚本段错误而崩溃.
1 #!/bin/bash 2 3 # 警告: 运行这个脚本可能使你的系统失去响应! 4 # 如果你运气不错,在它使用完所有可用内存之前会段错误而退出. 5 6 recursive_function () 7 { 8 echo "$1" # 使函数做些事情以加速产生段错误. 9 (( $1 < $2 )) && recursive_function $(( $1 + 1 )) $2; 10 # 当第一个参数比第二个参数少时, 11 #+ 把第1个参数增1再次递归. 12 } 13 14 recursive_function 1 50000 # 递归 50,000 次! 15 # 非常可能段错误 (依赖于栈的大小,它由ulimit -m设置). 16 17 # 这种深度的递归甚至可能由于耗尽栈的内存大小而引起C程序的段错误. 18 # 19 20 21 echo "This will probably not print." 22 exit 0 # 这个脚本将不会从这儿正常退出. 23 24 # 多谢, St閜hane Chazelas.