C语言提高之——函数运用(参数、递归)

本文深入探讨C语言中函数的使用,强调理解函数参数传递的实质是值传递,介绍了如何实现可变参数列表,并通过递归概念的讲解及阶乘计算实例,讨论了递归与迭代的优劣,引导读者理解何时选择递归方法。
摘要由CSDN通过智能技术生成

理解:

    想用好函数应该对函数有一个充分的理解,如果不能充分理解函数,运用起来也会容易产生问题。关于函数的理解大家可以参考这篇博客:函数再理解!。下边就在下边在运用上做一些相关说明。

参数:

    参数传递:

    首先说明在C语言中函数参数的传递都是以传值的方式调用的。要实现在其他语言中看似传址的功能,那么把要操作的数所在的地址这个数当做参数传递就可以了。其实说白了所有的传递都是数的传递,只不过传址传递的是地址数据罢了。就如同所有的数组其实都是一维的,只是为了用的方便人们人为的将其分为了二维和多维的罢了。

    可变参数列表:

    我们一般用的函数都是一定的参数和类型,但是例如有时候传递的参数的数量和类型需要用户在运行软件期间获取,那么就需要可变的参数列表了。

可变参数列表是通过stdarg这个宏来实现的。这个宏定义在stdarg.h头文件,同时定义了一个va_list类型和va_start、va_arg、va_end三个宏。在定义的函数声明可如下形式:

<span style="font-size:24px;">函数名(int n_values,…)</span>

    其中1、va_start用来初始化,参数为va_list变量名和省略号前最后一个有名参数。2、va_arg用来访问和返回参数,参数为va_list变量名和参数列表的下一个参数类型。3、va_end用来在最后取完所有参数后从函数返回,参数是va_list变量名。

运用之——递归:

    说到递归大家都已经很熟悉,简单的定义就是直接或间接调用自身的函数。但是我们经常拿来说明递归的例子:计算阶乘和斐波那契数列的例子其实并不可以从根本上来说明递归功能的真正目的。

    下边就是我们常用来说明递归的例程:用递归实现计算n的阶乘。

<span style="font-size:24px;">/*
**用递归方法计算n的阶乘
*/

long
factorial(int n)
{
	if( n <= 0 )
		return 1;
	else
		return n * factorial( n - 1 );
}</span>

    但是这样用递归是有缺陷的,其中因为其中每次对函数的递归调用都会产生很多运行时开销;其实如果函数在递归调用返回之后不再执行任何任务,那么这个递归函数完全可以用迭代计算来替换,当然前提是需要在可读性和运行开销上做一定的权衡。下边就是上边的程序用迭代方法实现的过程。

<span style="font-size:24px;">long
factorial(int n)
{
	int result = 1;

	while( n > 1 )
	{
		result *= n;
		n -= 1;
	}
	return result;
}</span>

    其实针对这个例子来看,两者的可读性差不太多,但是后者的运行开销要比前者少很多。由此看来后者要优于前者,但是那么什么时候应该用递归呢?看看下边的这个程序:接受一个整型值(无符号),将其转化为字符打印。

<span style="font-size:24px;">/*
** 接受一个整型值(无符号),转化为字符并打印。
*/
#include <stdio.h>

void
binary_to_ascii( unsigned int value )
{
	unsigned int quotient;

	quotient = value / 10;
	if( quotient != 0 )
		binary_to_ascii( quotient );
	putchar( value % 10 + '0' );
}</span>

    这个程序和第一个程序对比可以发现,这个程序中函数在调用自身之后还做了一些其他的操作,而第一个程序则什么也没有做。对比可以发现更能体现递归强大功能的是,在函数中当函数调用自身之后,即在每一层函数被调用返回之后还需要对返回信息做进一步操作的时候更适合用递归。要深入理解这一点需要从根本上理解递归这个东西。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值