8.1.5.4 函数的嵌套和递归调用

u  函数的嵌套调用

M语言中,任意一个函数的定义都是独立的,不允许在一个函数的定义中再定义另一函数。函数之间都是平等的、平行的,即不允许函数的嵌套定义。但允许在一个函数的定义中调用另一函数,即允许函数的嵌套调用。嵌套函数的调用返回时将根据嵌套层次逐层返回。如下图所示,这里给出了函数f中调用函数g,函数g中又调用函数h,然后逐层返回的情形,代码如下:

void  f( )

{

   …

   g( );

   …

  return ;

}

void  g( )

{

   …

   h( );

   …

  return ;

}

void  h( )

{

   …

   …

  return ;

}

例如:程序清单中所列的代码就是函数的嵌套调用示例,程序功能为计算的值。

程序清单  函数的嵌套调用示例

主程序:

    int  k, n ,result;

    k = 4;

    n = 6;

    result = sump( k ,n );

自定义函数:

     int  powers (int  n, int  k)

     {

       int  i, product;

       i = 1;

       product = 1;

       while ( i <= k)

        {

          product = product * n;

i = i+1;

}

           return  product;

}

int  sump (int  k, int  n)

{

  int  i, sum;

  i = 1;

  sum = 0;

  while (i <= n)

   {

    sum = sum + powers (i , k);

    i = i + 1;

}

  return  sum ;

}

程序清单中,函数powers用来计算的值,而函数sump通过调用函数powers来求的值,主程序用变量result调用sump来输出计算的结果。

程序执行结束后,result的值为:从164次幂之和 = 2275

u  函数的递归调用

如果一个函数在其函数体中直接或者间接地调用了自己,则该函数称为递归函数。直接调用自己为直接递归;间接调用自己为间接递归。这两种调用在M语言中都是支持的。

在解决某些复杂问题时,常常采用一种分而治之的设计手段,即把一个问题分解成若干个子问题,而每个子问题的性质与原来问题相同,只是它们的规模比原问题要小,这时,可以通过对各个问题进行求解和综合来解决整个问题,而每个子问题的求解过程也可以采用与原问题相同的分解与综合的方式来解决。递归函数为上述设计方法提供了一种自然、简洁的实现机制。比如,在程序设计中经常需要实现重复性的操作。循环为实现重复操作提供了一种途径,而采用递归函数就是另一途径。

例如,求n阶勒让德多项式,公式为:

对于该问题而言,当n不为01时,求的问题可以分解成求的问题,然后求他们的综合。而求的问题与求是同性质的问题,只是它们的级数小了些而已。

对该问题,当你n = 0 n = 1 时,可直接得到结果1x;当n>1时,可先求第n-1阶和第n-2阶勒让德多项式的值,然后计算他们的综合即可得到第n阶勒让德多项式的值。解决该问题的递归函数程序如程序清单所示。

程序清单  n阶勒让德多项式的值的递归函数

主程序:

        int  result;

        result = poly(10,3);

自定义函数:

        double poly (int n ,double x)

        {

          if (n == 0)

           {

            return 1;

            }

          if (n == 1)

            {

             return x;

             }

          return  ( (2*n - 1) * poly( n-1 , x) - (n-1) * poly (n-2 , x))/2;

          }

执行程序后,输出结果为:

result的值poly(10,3) = 6.85794 

 注意: 递归法解决问题的关键有以下两点。

           1)善于归纳问题的递归特征:将原问题转化为一个新的问题,而这个新的问题与原问题有相同的解决方法。继续这种转化,直到转化出来的问题是一个有已知解的问题为止。

       2)善于分析和总结问题的递归求解结束条件:只有有限次递归才有实际意义。