一、函数
一)、函数-调用过程
package main
import "fmt"
func main() {
//调用test
n1 := 10
test(n1)
fmt.Println("main n1", n1) //10
}
//编写一个数 test
func test(n1 int) {
n1 += 1
fmt.Println("test n1", n1) //11
}
Go语言中基本数据类型的传递是值传递,所以上例中两个n1值之所以不同是因为程序启动时,定义的n1复制了一份值给了test()函数中的n1,而test函数中因为执行了计算改变了复制而来的n1的数值所以打印为11,而test()函数中的n1和main()函数中的n1相互并不影响。
(1)在调用一个函数时,会给该函数分配一个新的空间,编译器会通过自身的处理让这个新的空间和其他的栈的空间区分开。 (2)在每个函数对应的栈中,数据空间是相互独立的。(3)当一个函数调用完毕,程序会销毁这个函数对应的栈空间。
二)、return语句
Go函数支持返回多个值,在其他的编程语言中如果想返回多个值,需要将多个值封装起来返回
package main
import "fmt"
func main() {
/*
func 函数名(形参列表 数据类型)(返回值类型列表){
代码块
return 返回值列表
}
*/
sum := getSum(10, 20)
fmt.Println("main sum", sum)
}
func getSum(n1, n2 int) int {
sum := n1 + n2
fmt.Println("getSum sum=", sum)
return sum
//当函数有return语句时,就是将结果返回给调用者
//即谁调用就返回给谁
}
(1)如果返回多个值,在接收时,希望忽略掉某个值,则使用_符号表示占位忽略 (2)如果返回值只有一个 返回值类型列表可以不用写()
二)、函数的递归调用
一个函数调用函数本身则称为函数递归调用
package main
import "fmt"
func main() {
test(4)
}
func test(n int) {
if n > 2 {
n--
test(n)
}
fmt.Println("n=", n) // 2 2 3
}
递归后调用的顺序如图(从下往上)打印结果顺序是从上到下,因为递归时最外层相当于处在阻塞状态,去调用内层的递归函数,当条件不成立时,就会从最内层执行返回到最外层,所以最内层会先打印,打印后栈区销毁。(个人感觉和多个defer逆序执行挺像的)。
二、递归练习
一)、斐波那契数
使用递归的方式,求出斐波那契数列 1,1,2,3,5,8,13
给定一个整数n,求出他的斐波那契数是多少。
其实就是给定一个斐波那契数的下标,求这个下标对应的斐波那契值。
package main
import "fmt"
func main() {
/*
使用递归的方式,求出斐波那契数列 1,1,2,3,5,8,13
给定一个整数n,求出他的斐波那契数是多少
*/
res := fbn(3)
fmt.Println("res=", res)
}
func fbn(n int) int {
//思路:斐波那契数列以如下被以递推的方法定义:
//F(0)=0,F(1)=1,F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)
if n == 1 || n == 2 {
return 1
} else {
return fbn(n-1) + fbn(n-2)
}
}
二)、求函数值
已知f(1)=3;f(n)=2*f(n-1)+1,使用递归的思想编程,求出f(n)的值;递归流程上边分析过
package main
import "fmt"
func main() {
fmt.Println("f(1)", f(1)) //1
fmt.Println("f(3)", f(3)) //15
fmt.Println("f(5)", f(5)) //63
}
func f(n int) int {
if n == 1 {
return 3
} else {
return 2*f(n-1) + 1
}
}
三)、猴子吃桃
有一堆桃子,猴子第一天吃掉其中的一半,并在多吃了一个!
以后每一天猴子都吃掉其中的一半多一个,当到第十天的时候,发现此时只有一个桃子了(还没吃)。
最初有多少个桃子?
package main
import "fmt"
func main() {
/*
思路:反推
1.第十天有一个桃子
2.第九天=(第十天的桃子+1)*2
第n天的桃子数量 f(n) = (f(n+1)+1)*2
*/
fmt.Println("第一天的桃子数量", peach(1)) //1534
}
func peach(n int) int {
if n == 10 {
return 1
} else {
return (peach(n+1) + 1) * 2
}
}
这个猴子还挺能吃!