C语言基础知识:函数的调用

函数的定义

一般来说,执行源程序就是执行主函数main,其他函数只能被主函数所调用,而其他函数之间也可以相互调用。

1.标准库函数:

分为:I/O函数,字符串,字符处理函数,数学函数,接口函数,时间转换和操作函数,动态地址分配函数,目录函数,过程控制函数,字符屏幕和图形功能函数。

这些库函数在不同的头文件中声明。比如:

math.h头文件中有:sin(x),cos(x),exp(x)(求e^x),fabs(x)(求x的绝对值)等库函数。

stdio.h头文件中有:scanf(),printf(),gets(),puts(),getchar(),putchar()等库函数。

string.h头文件中有:strcmp(),strcpy(),strcat(),strlen等库函数。

2.函数的定义:

(1)定义无参函数:

类型名  函数名()

{

函数体

}

or

类型名  函数名(void)

{

函数体

}

(2)定义有参函数

类型名 函数名(形式参数表列)

{

函数体

}

(3)定义空函数

类型名 函数名()

{    }

函数的调用

1.函数调用时的参数传递

函数间通过参数来传递数据,即通过主调函数中的实际参数(实参)向被调用函数中的形式参数(形参)进行传递。

实参向形参传递数据的方式:实参将值单向传递给形参,形参的变化不影响实参值。

for example:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int a, b;
	void swap(int a, int b);		//函数声明
	scanf("%d%d", &a, &b);		//键盘输入
	swap(a, b);		//函数调用
	printf("最终的a,b值:\n  a=%d b=%d\n", a, b);
	system("pause");
	return 0;
}
void swap(int a, int b)
{
	int t;
	if (a < b)
	{
		t = a;
		a = b;
		b = t;		//a中放大值,b中放小值
	}
	printf("自定义函数的a,b值:\n  a=%d b=%d\n", a, b);
}

运行结果为:

分析:形参交换了数据,而实参保持原数据不变。这是单向的值传递,所以形参的值改变后而实参的值没有改变。

  • 形参在函数中是变量名,在函数调用时,形参被临时分配相应的内存,调用结束后,形参单元被释放,而实参单元保留并维持原值。
  • 实参是表达式,负责向对应的形参标识的内存单元传递数据,实参向形参的数据传递是“值传递”。
  • 实参与形参必须个数相同
  • 对应的形参和实参的类型必须一致

2.函数的返回值

(1)函数的返回值通过函数中的return语句获得。如果需要从调用函数带回一个函数值(供主函数使用),被调函数中需包含return语句。

for example:

int max(int x,int y)
{
    return(x>y?x:y);
}

(2)在定义函数时要指定函数值的类型

int max(float x,float y)            //函数值为整型
char letter(char c1,char c2)            //函数值为字符型
double max(int x,int y)            //函数值为双精度型

(3)函数类型决定返回值的类型。

3.函数的嵌套

定义函数时不能定义另一个函数,但是可以进行嵌套调用函数。

for example:

*用函数嵌套找出4个数中的最大值。

#include<stdio.h>
#include<stdlib.h>
int max2(int a, int b)			//找出a和b中的最大值
{
	if (a >= b)
	{
		return a;			//	a作为返回值
	}
	return b;				//	b作为返回值
}
int max4(int a, int b, int c, int d)	//定义找4个数最大值的函数
{
	int m;		//存最大值
	m = max2(a, b);		//调用max2函数,将a,b中大的值放在m中
	m = max2(m, c);		//调用max2函数,将a,b,c中大的值放在m中
	m = max2(m, d);		//调用max2函数,将a,b,c,d中大的值放在m中
	return m;		//返回到主函数
}
int main()
{
	int a, b, c, d;
	int max;
	printf("请输入四个数:\n");
	scanf("%d%d%d%d", &a, &b, &c, &d);
	max = max4(a, b, c, d);			//调用max4函数
	printf("最大数位:%d\n", max);
	system("pause");
	return 0;
}

函数的递归

1.递归概念:

函数的递归调用是指:一个函数在他的函数体内直接或间接地调用它自身。分为:直接递归(函数直接调用自身)和间接递归(函数通过其他函数调用自身)。可分为“回溯”和“递推”两个阶段。

2.递归函数的一般形式:

反值类型   递归函数名(参数说明表)

{

if(递归终止条件)

返回值=递归终止值;

else

返回值=递归调用(...)的表达式;

return 返回值;

}

3.递归函数举例:

*用递归求n的阶乘。

#include<stdio.h>
#include<stdlib.h>
int fac(int n)		//定义函数
{
	int f;
	if (n < 0)
		printf("数据错误\n");
	else if (n == 0 || n == 1)
		f = 1;
	else
		f = n* fac(n - 1);			//n!=n*(n-1)
	return f;			//返回主函数
}
int main()
{
	int n, y;
	printf("请输入n的值\n");
	scanf("%d", &n);
	y = fac(n);		//这里n为实参
	printf("%d!=%d\n", n, y);
	system("pause");
	return 0;
}

汉诺塔问题为经典的递归调用实例。代码如下:

#include<stdio.h>
#include<stdlib.h>
void move(char x, char y)	//输出移盘方案
{
	printf("%c->%c\n", x, y);
}
void hanoi(int n, char one, char two, char three)		//移盘
{
	if (n == 1)
		move(one, three);		//如果是1个盘,直接从第一个座移到第3个座上
	else
	{
		hanoi(n - 1, one, three, two);		
		move(one, three);
		hanoi(n - 1, two, one, three);
	}
}
int main()
{
	int n;
	printf("输入盘的个数\n");
	scanf("%d", &n);
	printf("移盘的步骤:\n");
	hanoi(n, 'A', 'B', 'C');
	system("pause");
	return 0;

分析:将n个盘子从A座上移到C座上需要三步:

(1)将A上的n-1个盘子借助C座先移到B座上;

(2)把A座上剩下的一个盘子移到C座上;

(3)将n-1个盘从B座上借助于A移到C座上。

 

4、函数递归的定义和优缺点

程序调用自身的行为就是递归。可以直接或间接的调用,本质是把复杂的问题转化为一个规模小的问题。递归一般只需少量的代码就可描绘出多次重复计算。其主要思考方式在于大事化小

优点是为具有某些特征的编程问题提供了最简单的策略,缺点是层层调用,算法的复杂度可能过高,以致于快速耗干了计算机的内存资源,不方便阅读和维护等。

5、递归的使用场景及必要条件

使用场景

  1. 能够要求转化为新的问题,且二者解决方法相同,所处理的对象存在规律变化。
  2. 非递归比较麻烦,而递归很简单。
  3. 有模板或是公式可以直接套用,不会出现明显问题。

必要条件

  • 明确存在限制条件
  • 每次递归越来越逼近条件

6、递归的细节说明

  • 每级递归都有自己的变量,可能名称相同,但是其值不同。

    递归调用时,系统自动保留当前函数的参数变量。每次调用系统都会为函数开辟相应的空间。

  • 每次调用都要返回值,递归执行结束后,控制权传回到上一级函数。

    调用结束后,系统释放本次调用所开辟的空间,程序返回到上一次的调用点,同时获得初进该级调用的参数。

    每级递归必须逐级返回,不可跳跃或间断。

  • 函数中递归语句之前的代码,按被调函数的顺序执行,递归之后的代码,与被调函数相反的顺序执行。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值