C语言-第36课

第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 ", func(4));

    return 0;

}

运行结果:4= 24

虽说调用了一次,却创建了4次活动记录。所以说我们的递归函数不能递归太多的层次。

 

小结:

C语言中的递归函数必然会使用判断语句。

递归函数在需要编写的时候定义函数的出口,否则栈会溢出。

递归函数是一种分而治之的思想。

 

思考题:编写一个函数打印一个字符数组的全排列。

void Permutation(char *pStr,char *pBegin)
{
 assert(pStr&&pBegin);
 if(*pBegin == '') 
  printf("%s ",pStr);   
 else 
    {        
  for(char *pCh=pBegin; *pCh !=''; 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)   //会出错,永远不会进入。

{   //...  }

 

原文地址:https://www.cnblogs.com/free-1122/p/9826649.html