遞迴函式,可變引數列表
遞迴
1.什麼是遞迴?
遞迴就是函式或過程在其定義或宣告的中有直接或間接呼叫自身的一種方式。他通常將一個大型複雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解。
2.遞迴的主要思想:大事化小
求第n個斐波那契數(不考慮溢位)
int fib(int n)
{
if (n <= 2)
return 1;
return fib(n-1) + fib(n - 2);
}
求n的階乘:
int factorial(int n)
{
if (n <= 1)
return 1;
else
return n*factorial(n - 1);
}
不允許建立臨時變數,求字串長度
int my_strlen(char* str)
{
if (*str == '\0')
return 0;
else
return 1 + my_strlen(str + 1);
}
3.遞迴的倆個必要條件
- 存在限制條件,當滿足這個限制條件的時候,遞迴便不在繼續(遞迴要有出口)
- 每次遞迴之後越來越接近這個限制條件
4.遞迴的缺點
- 系統分配給程式的棧空間是有限的,單數如果出現了死迴圈,死遞迴等問題,就可能導致一直開闢空間,最終產生棧空間耗盡的情況,這樣的現象我們叫做棧溢位
- 遞迴雖然使程式的可讀性強,思維邏輯更清晰,但其效率低
5.如何解決上述問題:
- 將程式由遞迴改為非遞迴
- 在遞迴內部使用static(棧物件)物件代替非static區域性變數(棧物件),這樣就不用頻繁的去申請和釋放棧空間
- 建議使用第一種方法
可變引數列表
c語言可以通過可變引數列表來實現一個函式,使得函式可以接受一個以上任意多個引數(不固定)
- 在函式定義的時候引數列表至少明確的定義一個引數,其餘的可變引數列表用...表示
實現一個求平均數的函式,給的任意的數字,求他們的平均數
int average(int n, ...)
{
va_list arg;
int i = 0;
int sum = 0;
va_start(arg, n);
for (i = 0; i < n; i++)
{
sum = sum + va_arg(arg, int);
}
return sum / n;
va_end(arg);
}
int main()
{
int a = 1;
int b = 2;
int c = 3;
int vag1 = average(2, a, c);
int vag2 = average(3, a, b, c);
printf("vag1 = %d\n", vag1);
printf("vag2 = %d\n", vag2);
system("pause");
return 0;
}
//用n表示接收引數的個數,...表示可變引數列表
- 可變引數列表要通過四個巨集來輔助完成
1)這四個巨集的標頭檔案#include<stdarg.h>
2) va_list,用來宣告一個變數,變數的型別為va_list,他用於訪問引數列表未確定的部分
3)這個變數是呼叫va_start來初始化的,va_start(arg,n)他的第一個引數是va_list的變數名,第二個引數是省略號前最後一個有名字的引數,初始化過程把arg變數設定為指向可變引數部分的第一個引數。
4)為了訪問引數,需使用va_arg,這個巨集接受倆個引數,va_list變數和引數列表中下一個引數的型別
5)最後,當訪問完最後一個可變引數之後,我們需要呼叫va_end,將指標置空。
- 注意事項:
1)引數列表必須從頭到尾逐個訪問,如果你訪問了幾個就想終止,或者是一開始就緒從中間訪問,都是不行的。
2)這些巨集都沒有辦法檢查引數型別,如果在使用va_arg時指錯了引數型別,後果不堪設想
3)這些巨集無法直接判斷實際存在引數的數量
可變引數的實現過程其實就是使用這些巨集來輔助完成的
相關文章
- PHP 函式可變數量的引數列表PHP函式變數
- php實現函式可變引數列表PHP函式
- 遞迴函式-樹形列表遞迴函式
- PHP函式,引數,可變參函式.PHP函式
- C++ 可變引數模板遞迴展開C++遞迴
- Go函式接收可變引數Go函式
- Python 函式(可變引數)Python函式
- C++ 函式的可變引數C++函式
- C可變引數函式 實現函式
- php函式之如何用預設引數和可變長度引數方式傳遞?PHP函式
- Python函式引數傳遞以及變數作用域Python函式變數
- JavaScript函式傳遞引數JavaScript函式
- 函式的引數傳遞函式
- JavaScript函式引數傳遞JavaScript函式
- golang學習之路之函式可變引數Golang函式
- 遞迴函式遞迴函式
- 遞迴、三元表示式、生成式(列表,字典)、匿名函式遞迴函式
- Java方法04:命令列傳遞引數、可變引數Java命令列
- Swift 呼叫 Objective-C 的可變引數函式SwiftObject函式
- 函式作為引數傳遞函式
- 函式引數傳遞及返回函式
- 函式表示式–遞迴函式遞迴
- 函式的遞迴函式遞迴
- JavaScript 函式遞迴JavaScript函式遞迴
- php遞迴函式PHP遞迴函式
- 函式之遞迴函式遞迴
- 自己實現一個簡單可變引數函式函式
- python函式之引數傳遞Python函式
- java基礎(九) 可變引數列表介紹Java
- 函式遞迴與生成式函式遞迴
- python---函式引數、變數Python函式變數
- TypeScript 函式可選引數和預設引數TypeScript函式
- 遞迴函式的理解遞迴函式
- 方法的過載、可變形參的方法、方法的引數值傳遞機制、遞迴方法遞迴
- python函式變長引數Python函式
- python中函式的引數傳遞Python函式
- php函式引用傳遞引數的方法PHP函式
- JavaScript 事件處理函式傳遞引數JavaScript事件函式