lua程序设计第六章函数的用法以及练习题答案
函数调用需要使用圆括号把参数列表括起来,当函数只有一个参数,且参数是字符串常量或者表构造器时,括号可以不用加
print "Hello world" <--> print("Hello world")
f{x = 10, y = 20} <--> f({x = 10, y = 20})
参数的行为与局部变量的行为完全一致,相当于值为参数值的一个局部变量。
调用函数时使用的参数个数可以与定义函数使用的参数个数不一致,lua会通过抛弃多余参数和将不足的参数设为nil的方式来调整参数的个数
function f (a,b)
print(a,b)
end
f() -->nil nil
f(3,4,5) --> 3 4 (5被抛弃)
lua允许一个函数返回多个结果
s,e = string.find("hello Lua users", "Lua")
print(s,e) --> 7 9
function foo0()
end
function foo1()
return "a"
end
function foo2()
return "a", "b"
end
x,y = foo2() -- x ="a", y = "b"
x = foo2() -- x = "a", "b"被抛弃
x,y,z = foo2() -- x = "a", y = "b", z = nil
x,y = foo2(), 20 -- x = "a", y = 20
表构造器会完整地接受函数调用的所有返回值,不会调整返回个数
t = {foo2()} -- t = {"a", "b"}
不过这种行为只有当函数调用是表达式列表中最后一个时才有效
t ={foo(),foo2(),4} --t[1] = nil, t[2] = "a", t[3] == 4
将函数调用用一对圆括号括起来可以强制其只返回一个结果
print((foo2())) --> a
return语句后面的内容是不需要加括号的,形如return(f(x))的语句只返回一个值
可以使用…表示该函数的参数是可变长的
如:
function add(...)
local s = 0
for _, v in ipairs{...} do
s = s + v
end
return s
end
print(add(3,4,10,25,12)) -->54
具有可变长参数的函数也可以具有任意数量的固定参数,但固定参数必须放在变长参数之前
table.pack函数像表达式{…}一样保存所有的参数,然后将其放在一个表中返回,
其外,这个表还有一个保存了参数个数的额外字段"n".
function nonils(...)
local arg = table.pack(...)
for i = 1, arg.n do
if (arg[i]== nil) then
return false
end
end
return true
end
函数select,具有一个固定的参数selector,以及数量可变的参数,可用来遍历函数的可变长参数
print(select(1,"a","b","c")) --> a b c 返回第一个参数后的所有参数
print(select("#","a","b","c")) --> 3 返回额外参数的总数
函数table.unpack 参数是一个数组,返回值为数组内的所有元素,与table.pack的功能相反
print(table.unpack{10,20,30}) -->10 20 30
正确的尾调用
当一个函数的最后一个动作是调用另一个函数而没有在进行其他工作时,就形成了尾调用。
function f(x)
x = x + 1;
return g(x)
end
当g返回时,程序的执行路径会直接返回到调用f的位置。程序也就不需要在调用栈中保存有关调用函数的任何信息,利用这个特点,使得在进行尾调用时不使用任何额外的栈空间.这种实现称为尾调用消除
function f(x)
g(x)
end
上述的不是尾调用,因为f(x)调用了g(x)后,在返回前还不得不丢弃g返回的所有结果。
类似的下面的也是
return g(x) + 1 --必须进行假发
return x or g(x) --必须把返回值限制为1个
return (g(x)) --必须把返回值限制为1个
练习6.1
function printArr(a)
for i=1,#a do
print(a[i])
end
end
练习6.2
function selecttable(...)
return select(2,...)
end
a = table.pack(selecttable(1,2,3))
for i = 1, #a do
print(a[i])
end
练习6.3
function selecttable(...)
local a = table.pack(...)
a[a.n] = nil
return table.unpack(a)
end
print(selecttable(1,2,3,4,5))
6.4
Knuth-Durstenfeld Shuffle 洗牌算法
function Shuffle(arr)
math.randomseed(os.time())
for i = #arr, 1,-1 do
index = (math.random(i) % (i+1))
local temp = arr[index]
arr[index] = arr[i]
arr[i] = temp
end
return arr
end
a = {1,2,3,4,5,6,7,8,9,10}
print(table.unpack(Shuffle(a)))
下一篇: 微信红包发送问题