1. 程式人生 > >C語言-第36課 - 函數遞歸與函數設計技巧

C語言-第36課 - 函數遞歸與函數設計技巧

分而治之 andro 相同 tchar sse family tdi char s pri

第36課 - 函數遞歸與函數設計技巧

一. 遞歸

  1. 遞歸概述

(1) 遞歸是數學領域中的概念在程序設計中的應用。

(2) 遞歸是一種強有力的程序設計的方法。

(3) 遞歸的本質為函數內部在適當的時候調用自身。

  1. 組成部分

(1)遞歸點:以不同參數調用自身。

(2)出口:不在遞歸調用

下面就是求一個數的階乘的函數:

#include <stdio.h>

int func(int x)

{

if( x > 1 )

{

return x * func(x - 1); //遞歸點

}

else

{

return 1; //出口

}

}

int main()

{

printf("x! = %d\n", func(4));

return 0;

}

運行結果:4= 24

雖說調用了一次,卻創建了4次活動記錄。所以說我們的遞歸函數不能遞歸太多的層次。

小結:

C語言中的遞歸函數必然會使用判斷語句。

遞歸函數在需要編寫的時候定義函數的出口,否則棧會溢出。

遞歸函數是一種分而治之的思想。

思考題:編寫一個函數打印一個字符數組的全排列。

void Permutation(char *pStr,char *pBegin)
{
assert(pStr&&pBegin);
if(*pBegin == ‘\0‘)
printf("%s\n",pStr);
else
{
for(char *pCh=pBegin; *pCh !=‘\0‘; pCh++)
{
char temp = *pCh;
*pCh = *pBegin;
*pBegin = temp;

Permutation(pStr, pBegin+1);
temp = *pCh;
*pCh = *pBegin;
*pBegin = temp;
}
}
}

二. 函數的設計技巧

  1. 不要在函數中使用全局變量,盡量讓函數從意義上是一個獨立的功能模塊。
  2. 參數名要能夠體現參數的意義。

void str_copy(char *str1, char *str2);

void str_copy(char *str_dest, char *str_src);

  1. 如果函數是指針,且僅作為輸入參數用,則應在類型前加const,以防止該指針在函數體內被意外修改。

void str_copy(char *str_dest, const char *str_src);

  1. 不要省略返回值的類型,如果函數沒有返回值,那麽應該聲明為void類型。
  2. 在函數體的“入口處”,對參數的有效性進行檢查,對指針的檢查尤為重要。
  3. 語句不可返回指向“棧內存”的“指針”,因為該內存在函數體結束時被自動銷毀。
  4. 函數體的規模小,盡量要控制在80行代碼之內。
  5. 相同的輸入應當產生相同的輸出,盡量避免函數帶有“記憶”功能。
  6. 避免函數有太多的參數,參數的個數盡量控制在4個以內。
  7. 有時候函數不需要返回值,但是為了增加靈活性,加支持鏈式表達,可以附加返回值:

char s[64];

int len = strlen(strcpy(s,”android”));

  1. 函數名與返回值類型在語義上不可以沖突

char c;

c = getchar(); //getchar的返回值是int不是char

if(EOF==c) //會出錯,永遠不會進入。

{ //... }

C語言-第36課 - 函數遞歸與函數設計技巧