一.函数的调用机制
函数的调用中,一般是通过方法来操作的,那么如何理解方法这个概念呢,先举个列子:
函数的调用过过程
为了让大家更好地理解函数的调用过程,看一个例子:
1).传入一个数n1,再n1 +1 test(n1 int)
对上图的说明:
(1).在调动该函数时,会给函数分配一个空间,编译器会通过自身的处理让这个新的空间和其他的栈的空间区分开来
(2).在每个函数对应的栈中,数据空间是相互独立的,不会混淆
(3).当一个函数调用完毕(执行完毕)后,程序会销毁这个函数对应的栈空间
return语句
基本语法
go函数支持返回多个值,这个是其他编程语言没有的
func 函数名(形式参数) (返回值类型列表) {
语句...
return 返回值列表
}
1).如果返回多个值时,在接收时,希望忽略某个返回值,使用 _ 符号表示占位忽略
2).如果返回值只有一个,(返回值类型列表) 可以不写()
举例说明:
package main import ( "fmt" ) func test(n1 int) { n1 += 1 fmt.Println("n1:",n1) } //编辑一个函数,可以计算两数的和,差,并返回结果 func getData(num1 int, num2 int) (int, int) { sum := num1 + num2 cha := num1 - num2 return sum, cha } func main() { n1 := 10 //调用test test(n1) fmt.Println("n1:",n1) resSum, resCha := getData(10, 3) fmt.Printf("和:%v,差:%v",resSum, resCha) //希望忽略某个返回值,只用 _ 符号表示占位符 resSum1, _ := getData(10, 3) fmt.Printf("和:%v",resSum1) }
二.函数的递归调用
一个函数在函数体内又调用了本身,称为递归调用
//快速入门 func test(n int) { if n > 2 { n-- test(n) } fmt.Println("n = ", n) } func test2(n int) { if n > 2 { n-- test2(n) } else { fmt.Println("n = ", n) } }
思考: 当n=4时,上述两个方法分别输出什么?并分析原因
函数递归需要遵守的重要原则
1).执行一个函数时,就创建一个受保护的独立空间(新函数栈)
2).函数的局部变量是独立的,不会相互影响
3).递归必须向退出递归的条件逼近,否则就是无限循环
4).当一个函数执行完毕后,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁
//案例1: 斐波拉契数
//使用递归,求出斐波拉契数1,1,2,3,5,8,13...
//给你一个整数n,求出它的值是多少
//思路:
//当 n = 1 || n =2 时,返回: 1
//当 n >= 2时,返回值: f(n - 1) + f(n - 2)
func fbn(n int) int {
if n == 1 || n == 2 {
return 1
} else {
return fbn(n - 1) + fbn(n - 2)
}
}
//案例2: 求函数值
//已知f(1) = 3; f(n) = 2 * f(n -1) + 1;
//使用递归,求出f(n)的值
func f(n int) int {
if n == 1 {
return 3
} else {
return 2 * f(n -1) + 1
}
}
//案例3: 猴子吃桃子问题
//有一堆桃子,猴子第一天吃了其中的一半,并再多吃了一个,以后每天猴子都吃其中一半,然后多吃一个.当第十天时,想再吃(还没吃),发现只有一个桃子了.问:最初共有多少个桃子?
//思路分析:
//第10天只有一个桃子
//第9天有几个桃子 = (第10天的桃子 + 1) * 2
//规律: 第n天桃子数据: peach(n) = (peach(n + 1) + 1) * 2
//n范围1~10
func peach(n int) int {
if (n > 10 || n < 1) {
fmt.Println("输入的天数错误")
return
}
if n == 10 {
return 1
} else {
return (peach(n + 1) + 1) * 2
}
}