第七章 递归与可变参数

一、递归

递归函数在每次递归调用后必须越来越接近某种限制条件,当满足这个限制条件后,便不再调用。

实例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;
		}
	}
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值