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

理解:

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

参数:

参数传递:

首先说明在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>

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

时间: 2024-08-26 04:06:27

C语言提高之——函数运用(参数、递归)的相关文章

用C语言写一个函数返回参数二进制中1的个数

首先,给出正确的C语言代码如下: #include <stdio.h> int count_one_bits(unsigned int value) { int count =0; while(value) { if(value%2==1) { count++; } value=value/2; } return count; } int main() { unsigned int num=0; int ret=0; scanf("%d",&num); ret=co

【C语言】主函数的参数探幽

在C语言中,我们编写代码中最不可缺少的是主函数. 然后其中在主函数main中其实也存在参数: 我们查看一下MSDN,然后我们看一下MSDN对于主函数的解释 看到了吗,main函数中存在3个参数,argc指的是命令数,argv指的是命令存储是什么,envp指的是环境变量. 然后我们来看一下命令行参数实现加减乘除: #include<stdio.h> #include <stdlib.h> #include <string.h> int main(int argc,char

C语言 编写一个函数,用递归方式求最大公约数。

编写一个函数,传入a,b两个int类型的变量,返回两个值的最大公约数.利用递归方式实现. #include <stdio.h> int gcd(int a,int b) { int tmp; if(a==0 || b==0) return 0; if(a<b) { tmp=a; a=b; b=tmp; } if(a%b==0) return b; else return gcd(b,a%b); } int main() { int num; num=gcd(12,4); printf(&

linux中c语言编程main函数和参数

linux下main函数的的标准调用函数的标准形式 int main(int char,char *argv[]) 在main函数的两个参数中,argc必须是整型变量,其是命令行的参数的数目,argv必须是指向字符串的指针数组,这些指针分别指向各个的命令行参数的地址. 原文地址:https://www.cnblogs.com/zoutingrong/p/12250466.html

c语言重载(overriding in C)或函数不定参数个数

google一下 c overiding发现有这样一段英文解释: Because C doesn't require that you pass all parameters to the function if you leave the parameter list blank in the prototype. The compiler should only throw up warnings if the prototype has a non-empty parameter list

C语言中main函数的参数详解

main函数的定义形式  main函数可以不带参数,也可以带参数,这个参数可以认为是 main函数的形式参数.C语言规定main函数的参数只能有两个,习惯上这两个参数写为argc和argv.所以C99标准中规定只有以下两种定义方式是正确的: int main(void) //无参形式 int main(int argc, char *argv[]) //有参形式 当然有参形式可以进行演变,所以下面的写法也是正确的(同时变量名是可以更换的): int main(int argc, char **a

main函数的参数(int argc,char *argv[])

一般的main函数都是不带参数的,因此main 后的括号都是空括号.实际上,main函数可以带参数,这个参数可以认为是 main函数的形式参数.C语言规定main函数的参数只能有两个, 习惯上这两个参数写为argc和argv.因此,main函数的函数头可写为: main (argc,argv)C语言还规定argc(第一个形参)必须是整型变量,argv( 第二个形参)必须是指向字符串的指针数组.加上形参说明后,main函数的函数头可以写为: main (int argc,char *argv[])

C语言之函数可变参数

先上一段代码: #include<cstdarg> #include<iostream> #include<string> using namespace std; void error(char* format,...){//至少要有一个参数,后边的...表示参数可变 va_list ap; int d,flag; char c, *s; va_start(ap,*format);//从args参数开始后面都是可变参数,va_start,va_end都为宏 while

【C语言】浅谈可变参数与printf函数

一.何谓可变参数 int printf( const char* format, ...); 这是使用过C语言的人所再熟悉不过的printf函数原型,它的参数中就有固定参数format和可变参数(用"-"表示). 而我们又可以用各种方式来调用printf,如: printf( "%d ",value); printf( "%s ",str); printf( "the number is %d ,string is:%s ",