一、递归
递归函数在每次递归调用后必须越来越接近某种限制条件,当满足这个限制条件后,便不再调用。
实例1:
/*
** 接受一个整形值(无符号),把它转换为字符并打印,前导零被删除。
*/
#include <stdio.h>
void binary_to_ascii(unsigned int value)
{
unsigned int quotient;
quotient = value / 10;
if(quotient != 0)
binary_to_ascii(qutient);
putchar(value % 10 + '0');
}
有些递归可以用迭代实现,效率更高。
实例2:
/*
** 用递归方法计算 n 的阶乘
*/
long factorial(int n)
{
if(n < 0)
return 1;
else
return n * factorial(n-1);
}
<pre name="code" class="cpp">/*
** 用迭代方法计算 n 的阶乘
*/
long factorial (int)
{
int result = 1;
while(n > 1){
result *= n;
n -= 1;
}
return result;
}
实例3:
/*
** 用递归方法计算第 n 个斐波那契数的值
*/
long fibonacci (int n)
{
if( n <= 2 )
return 1;
return fibonacci(n-1) + fibonacci(n-2);
}
/*
** 用迭代方法计算第 n 个斐波那契数的值
*/
long fibonacci (int n)
{
<span style="white-space:pre"> </span>long result;
<span style="white-space:pre"> </span>long previous_result;
<span style="white-space:pre"> </span>long next_old_result;
<span style="white-space:pre"> </span>result = previous_result = 1;
<span style="white-space:pre"> </span>while(n > 2){
<span style="white-space:pre"> </span>n -= 1;
<span style="white-space:pre"> </span>next_older_result = previous_result;
<span style="white-space:pre"> </span>previous_result = result;
<span style="white-space:pre"> </span>result = previous_result + next_older_result;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return result;
}
二、可变参数列表
可变参数列表是通过宏来实现的,这些宏定义越 stdarg.h 头文件。这个头文件声明了一个类型 va_list 和三个宏 —— va_start、va_arg 和 va_end/*
** 计算指定数量的值的平均值
*/
#include <stdarg.h>
float average( int n_values, ... )
{
va_list var_arg;
int count;
float sum = 0;
/*
** 准备访问可变参数
*/
va_start(var_arg, n_values);
/*
** 添加取自可变参数列表的值
*/
for( count=0; count<n_values; count+=1)
{
sum += va_arg(var_arg, int);
}
/*
** 完成处理可变参数
*/
va_end(var_arg);
return sum/n_values;
}
注意以上参数列表中的省略号:它提示此处可能传递数量和类型未确定的参数。
函数声明一个名叫 var_arg 的变量,它用于访问参数列表的未确定部分。这个变量通过 va_start 来初始化。它的第一个参数是 va_list 变量的名字,第二个参数是省略号前最后一个有名字的参数。初始化过程把 var_arg 变量设置为指向可变参数部分的第1个参数。为了访问参数,需要使用 va_arg ,这个宏接受两个参数:va_list 变量 和参数列表中下一个参数的类型。上面的例子中所有的可变参数都是整形。va_arg 返回这个参数的值,并使 var_arg 指向下一个可变参数。最后调用 va_end 结束。
实例2:简化的 printf 函数,它能够处理 %d、%f、%s 和 %c 的格式码
/*
** Bare–bones printf function: handles the %d, %f, %s, and %c format codes.
*/
#include <stdarg.h>
void printf( char *format, ... )
{
va_list arg;
char ch;
char *str;
va_start( arg, format );
/*
** Get the format characters one by one.
*/
while( ( ch = *format++ ) != ’\0’ ){
if( ch != ’%’ ){
/*
** Not a format code –– print the character
verbatim.
*/
putchar( ch );
continue;
}
/*
** We got a % –– now get the format code and use it to
format
** the next argument.
*/
switch( *format != ’\0’ ? *format++ : ’\0’ ){
case ’d’:
print_integer( va_arg( arg, int ) );
break;
case ’f’:
print_float( va_arg( arg, float ) );
break;
case ’c’:
putchar( va_arg( arg, int ) );
break;
case ’s’:
str = va_arg( arg, char * );
while( *str != ’\0’ )
putchar( *str++ );
break;
}
}
}