//續前節
目錄
5. 函式的嵌套呼叫和鏈式訪問
5.1 嵌套呼叫
5.2 鏈式訪問
6. 函式的宣告和定義
6.1 函式宣告:
6.2 函式定義:
7. 函式遞回
7.1 什么是遞回?
7.2 遞回的兩個必要條件
7.2.1 練習1:
7.2.2 練習2:
7.3 遞回與迭代
7.3.1 練習3:
7.3.2 練習4:
//今天我們就把函式部分肝完了哈,后面就開始陣列了,
5. 函式的嵌套呼叫和鏈式訪問
函式和函式之間可以根據實際的需求進行組合的,也就是互相呼叫的,
5.1 嵌套呼叫
#include <stdio.h>
void
new_line
()
{
printf
(
"hehe\n"
);
}
void
three_line
()
{
int
i
=
0
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
new_line
();
}
}
int
main
()
{
three_line
();
return
0
;
}
函式可以嵌套呼叫,但是不能嵌套定義,
5.2 鏈式訪問
把一個函式的回傳值作為另外一個函式的引數,
#include <stdio.h>
int main()
{
printf
(
"%d"
,
printf
(
"%d"
,
printf
(
"%d"
,
43
)));
//
結果是啥?
return
0
;
}


6. 函式的宣告和定義
6.1 函式宣告:
1.
告訴編譯器有一個函式叫什么,引數是什么,回傳型別是什么,但是具體是不是存在,函式
宣告決定不了,
2.
函式的宣告一般出現在函式的使用之前,要滿足
先宣告后使用
,
3.
函式的宣告一般要放在頭檔案中的,
6.2 函式定義:
函式的定義是指函式的具體實作,交待函式的功能實作,
test.h
的內容
放置函式的宣告
#ifndef __TEST_H__
#define __TEST_H__
//
函式的宣告
int
Add
(
int
x
,
int
y
);
#endif
//__TEST_H__
//目前不了解沒事哈后面講預處理的時候講,
test.c
的內容
放置函式的實作
#include "test.h"
//
函式
Add
的實作
int
Add
(
int
x
,
int
y
)
{
return
x
+
y
;
}

7. 函式遞回
7.1 什么是遞回?
程式呼叫自身的編程技巧稱為遞回(
recursion
),
遞回做為一種演算法在程式設計語言中廣泛應用, 一個程序或函式在其定義或說明中有直接或間接
呼叫自身的
一種方法,它通常把一個大型復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,
遞回策略
只需少量的程式就可描述出解題程序所需要的多次重復計算,大大地減少了程式的代碼量,
遞回的主要思考方式在于:把大事化小
7.2 遞回的兩個必要條件
- 存在限制條件,當滿足這個限制條件的時候,遞回便不再繼續,
- 每次遞回呼叫之后越來越接近這個限制條件,
7.2.1 練習1:
接受一個整型值(無符號),按照順序列印它的每一位,
例如:
輸入:
1234
,輸出
1 2 3 4.
綠色的箭頭回去的時候(歸)就依次列印1 2 3
//這個線看起來有點懵但是仔細理解其實也不難,就是一直呼叫自己同時判斷,然后一個一個出函式,
7.2.2 練習2:
撰寫函式不允許創建臨時變數,求字串的長度,


7.3 遞回與迭代
7.3.1 練習3:
求
n
的階乘,(不考慮溢位)
7.3.2 練習4:
求第
n
個斐波那契數,(不考慮溢位)

//在我們自己能寫出函式的時候,遞回是很簡單的,只是說有時候不能寫出函式就會難想一點,但也都是個熟能生巧的程序哈!
但是我們發現
有問題
;
在使用
fib
這個函式的時候如果我們要計算第
50
個斐波那契數字的時候特別耗費時間,
使用
factorial
函式求
10000
的階乘(不考慮結果的正確性),程式會崩潰,
為什么呢?
最后我們輸出看看
count
,是一個很大很大的值,
那我們如何改進呢?
在除錯
factorial
函式的時候,如果你的引數比較大,那就會報錯:
stack overflow
(堆疊溢位)
這樣的資訊,
系統分配給程式的堆疊空間是有限的,但是如果出現了死回圈,或者(死遞回),這樣有可能導致一
直開辟堆疊空間,最終產生堆疊空間耗盡的情況,這樣的現象我們稱為堆疊溢位,
那如何解決上述的問題:
1.
將遞回改寫成非遞回,
2.
使用
static
物件替代
nonstatic
區域物件,在遞回函式設計中,可以使用
static
物件替代
nonstatic
區域物件(即堆疊物件),這不
僅可以減少每次遞回呼叫和回傳時產生和釋放
nonstatic
物件的開銷,而且
static
物件還可以保
存遞回呼叫的中間狀態,并且可為
各個呼叫層所訪問,
比如,下面代碼就采用了,非遞回的方式來實作:
//
求
n
的階乘
int
factorial
(
int
n
)
{
int
result
=
1
;
while
(
n
>
1
)
{
result
*=
n
;
n
-=
1
;
}
return
result
;
}
//
求第
n
個斐波那契數

提示:
1.
許多問題是以遞回的形式進行解釋的,這只是因為它比非遞回的形式更為清晰,
2.
但是這些問題的迭代實作往往比遞回實作效率更高,雖然代碼的可讀性稍微差些,
3.
當一個問題相當復雜,難以用迭代實作時,此時遞回實作的簡潔性便可以補償它所帶來的運行時開
銷,
最后的最后,函式部分的內容就完成了哈!(當然后面進階c語言的時候又會再細講),今天的內容是有點難的,可能更多的是要去理解,嵌套呼叫,鏈式訪問,遞回,迭代好好理解,知道他每一步干什么,他的走向,其實就不會感覺那么難了哈!希望大家慢慢去思考,
要是覺得這篇文章對你有用的話,就來一個點贊加關注吧!!!
感謝觀看!!!
最后祝我們一起變好!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/348435.html
標籤:其他
上一篇:我的畢設實戰指南
下一篇:【JavaSE基礎】手把手教你玩轉Static關鍵字