函數

基本概念

 當一個的主函數太過龐大時,會將主函數按功能進行拆分,根據是否須要向外部提供接口,分爲靜態函數和普通函數,
普通的函數是跨文件可見的, 可是若是是靜態函數的話他的可見範圍會被縮小到本文件可見,外部文件是沒法進行調用的。函數

static int max (int x, int y) { //函數體 } 
 //靜態函數主要功能是能夠縮小該函數的可見範圍,減小函數重名的機率;
// 通常靜態函數會被定義在頭文件中,在須要使用的文件中能夠包含該文件便可使用。

遞歸函數

 若是一個函數內部有本身調用本身的語句,則它是遞歸函數。
 注意:
 emsp;1.遞歸函數必須有結束條件,否則會一直調用下去,將棧溢出,棧崩潰,最後致使程序異常退出;
 emsp;2.遞歸函數包含兩個過程,一個是逐層遞進,和逐步遞歸。指針

/*倒序打印 */
 void func( int num ){     
    if (num > 1){      

    func(num-1);   
 }     
    printf("%d\n" , num );      
 }

注意:
1.在遞歸函數使用的過程當中,棧空間消耗很是大,遞歸的層次越多棧空間剩餘空間間越少,很容易會把棧空間耗盡 。
2.在層層遞進的過程當中問題的規模,應該逐步減少,也就是某個形式參數應該逐步減少,每次遞歸判斷該形式參數是否知足返回條件。code

回調函數

 每一個函數都有一個入口地址,但調用此地址時就會調用此函數。函數指針就是用來保存函數的入口地址的,當函數的實現方不方便直接調用某個功能,可將函數的入口地址傳遞給函數指針,調用此函數指針即可以間接調用原來的函數,這種調用方式稱爲回調函數。遞歸

bool func_1( int (*p) (int ,int )); 
 int func_2(int a , int b); 
 int main(int argc, char const *argv[]) {     
    bool a = func_1(func_2);//func_2是一個函數的地址 
 if (a) { 

   printf("函數調用成功 !! \n");  
 }    
 else{ 

   printf("函數調用失敗 !! \n");   
 }      
 return 0; 
 } 
 bool func_1( int (*p) (int ,int ) ){  
   
   if ( NULL == p ){// 先判斷p是否指向一個NULL       
   return false ;   
 }         
 printf("我在函數1 !!\n");    
     
 int num = p(103 , 229);//經過函數指針P來調用函數func_2   
 printf("num:%d\n" , num);   
 return true ;
 } 
 int func_2(int a , int b){   

   return a<b ? a:b ; 
 }

注意:
1.傳遞和接收函數地址時&,*可省略。接口

//冪運算
 int exponentiation(int n, int i){

    if(i == 0){

         return 1;
    }
    else{

        return exponentiation(n, i-1)*n;
    }

}
//階乘
int Factorial(int n) {

   if(n == 1) {//使遞歸結束的條件

         return 1;//1! 等於1
   
       }
       else{//使遞歸進行的條件
 
         return(Factorial(n-1) * n);//n! = (n-1)! * n;
     }
}
相關文章
相關標籤/搜索