Go語言學習筆記 —— 函數調用機制解析

package main

import (
   "fmt"
)

func main01()  {
   /*
   return 語句
   基本語法:
   Go函數支持返回多個值,這一點是其它的語言沒有的。
   func 函數名 (形參列表) (返回值類型列表){
      語句...
      return 返回值列表
   }


   1.若是返回值多個值時,在接收時,但願忽略某個返回值,則使用_符號表示佔位忽略。
   2.若是返回值只有一個,(返回值類型列表),能夠不寫()


    */
   // 調用test
   n1 := 10
   test01(n1)
   fmt.Println("n1 = ",n1) // 輸出結果


}

// 一個函數test

func test01(n1 int){
   n1 = n1 + 1
   fmt.Println("n1",n1)
}

/*函數 - 遞歸調用
基本介紹
一個函數在函數體內又調用了自己,稱爲遞歸調用。

堆棧----先進後出


 */

func test02(n int)  {
   if n > 2{
      n--
      test02(n)
   }
   fmt.Println("n = ",n)
}

func test03(n int)  {
   if n > 2{
      n-- // 遞歸必須向退出遞歸條件接近,不然就會變成死循環。
      test02(n)
   }else{
      fmt.Println("n = ",n)
   }

}

func main02()  {

   fmt.Println("test01的輸出結果:")
   test01(4)

   fmt.Println("test02的輸出結果:")
   test02(4)

   fmt.Println("test03的輸出結果:")
   test03(4)



/*
函數的遞歸須要遵循的原則
   1.執行一個函數時,就建立一個新的受保護的獨立空間(新函數棧)
   2.函數局部變量是獨立的,不會相互影響。
   3.遞歸必須向退出遞歸的條件接近,不然是無限遞歸(死遞歸)
   4.當一個函數執行完畢時,或者遇到return,就會返回,遵照誰的調用,就將結果返回給誰。當函數執行完畢或者是返回時,函數自己也會被系統銷燬。
 */
fmt.Println("遞歸函數 —————— 練習題")

/*
遞歸調用 —— 練習題
 */

}

// 練習題1 斐波那契數

/*


 */


func fbn(n int)  int{

   if (n == 1 || n == 2) {
      return 1
   }else{
      return  fbn(n-1) + fbn(n-2)
   }
}

func main03()  {

   res := fbn(10)
   // 測試結果
   fmt.Println("遞歸函數 —————— 斐波那契數")
   fmt.Println("res = ",res)

}

/*
求函數值

f(1) = 3,f(n) = 2 * f(n-1) + 1
使用遞歸的方式

 */

func f( n int )  int{
   if n == 1 {
      return 3
   }else {
      return  2 * f(n-1) + 1
   }
}

func main04()  {
   // 測試結果是否正確
   fmt.Println("f(1 ) = ",f(1))
   fmt.Println("f(3) = ",f(3))
   fmt.Println("f(10) = ",f(10))
}

/*
猴子吃桃子問題 —————— 使用遞歸方式解決

猴子吃桃問題:猴子第一天摘下若干個桃子,立即吃了一半,還不過癮,又多吃了一個,
次日早上又將剩下的桃子吃掉一半,又多吃了一個。之後天天早上都吃前一天剩下的一半零一個。
到第10天早上想再吃時,見只剩下一個桃子了。求第一天共摘多少個桃子?

分析思路:
1.第10天只有一個桃子
2.第9天有幾個桃子 = (第10天桃子數量 + 1) *2
3.規律:第n天桃子數量 peach(n) = (peach(n + 1) + 1) * 2


 */

func peach(n int) int {

   if n > 10 || n < 1{
      fmt.Println("輸入的天數不對")
      return 0 // 表示沒有準確的數量
   }

   if n == 10 {
      return 1
   }else{
      return (peach(n + 1) + 1) * 2
   }
}

func main()  {

   // 測試
   fmt.Println("第1天的桃子數量爲:",peach(1))
   fmt.Println("第2天的桃子數量爲:",peach(2))
   fmt.Println("第3天的桃子數量爲:",peach(3))
   fmt.Println("第9天的桃子數量爲:",peach(9))
   fmt.Println("第10天的桃子數量爲:",peach(10))
   fmt.Println("第11天的桃子數量爲:",peach(11))

}

函數的注意事項和細節討論
1.函數的形參列表能夠是多個,返回值列表也能夠是多個數組

2.形參列表和返回值列表的數據類型能夠是值類和引用類型函數

3.函數的命名遵循表示法命名規範(首字母不能是數字,首字母大寫,
該函數能夠被本包文件和其餘的包文件使用,相似public,首字母小寫,只能被本包文件使用,其餘的文件不可以使用,相似private)學習

4.函數中的變量是局部的,函數外不會生效測試

5.基本數據類型和數組默認都是值傳遞,即進行值拷貝,在函數內修改,不會影響到原來的值。指針

6.若是但願函數內的變量能修改函數外的變量,能夠傳入變量的地址& , 函數內以指針的方式操做變量,效果上相似於引用。code

7.Go中函數不支持重載視頻

 

Go語言學習筆記來源:尚硅谷視頻課程遞歸

相關文章
相關標籤/搜索