学习Go语言的第二天

92 阅读3分钟

14.png

一、函数

一)、函数-调用过程

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相互并不影响。 函数调用内存图.png

(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
}

递归.png

递归后调用的顺序如图(从下往上)打印结果顺序是从上到下,因为递归时最外层相当于处在阻塞状态,去调用内层的递归函数,当条件不成立时,就会从最内层执行返回到最外层,所以最内层会先打印,打印后栈区销毁。(个人感觉和多个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
   }
}

这个猴子还挺能吃!