C语言入门-函数

目录

函数

函数定义

函数声明

函数参数

函数调用

函数调用过程

函数递归


函数

构成c程序的基本单元就是函数,函数中包括了程序的可执行代码。main函数作为c程序的入口和出口,如果把所有的代码都放到main函数里显得过于繁杂,我们将一个程序划分为若干个程序模块,每个模块负责编写代码一部分功能,这份实现某种功能的代码就是函数。

函数定义

定义函数包括两部分:函数头和函数体

函数头:返回值类型  (int )函数名(Add) 参数表(int a,int b)

函数体:包括局部变量的声明和函数的可执行代码

例如:

#include<stdio.h>
int Add(int a, int b)
{
	int z = 0;
	z = a + b;
	return z;
}
int main()
{
	int a = 10;
	int b = 20;
	int ret = Add(a, b);
	printf("%d\n", ret);
	return 0;
}

函数声明

int  Add(int a,int b);函数声明一般出现在函数使用之前,一般放到头文件中。

说明:一个源文件由一个或者多个函数组成,一个c程序可以由一个或者多个源文件组成,程序编译时以源文件为单位进行编译。

所有的函数互相独立,函数不能镶嵌定义,但是可以互相调用。

从用户角度看:函数分为两种 库函数和自定义函数。

库函数:由系统的提供的,可以直接使用的函数,引用头文件即可。

自己定义的函数:用户自己编写的实现所需功能的代码。

c语言要求:使用的所有函数必须:先定义后使用

函数参数

在调用函数时,大多数情况下,主调函数和被调函数之间有数据传递关系。

int   Add  (int a,int b)  函数参数

形式参数和实际参数

按名称理解:

形参:形式上存在, 实参:实际上存在

按作用理解:

形参:定义函数时,函数名后面括号内的变量就是“形参”。

实参:调用函数时,函数名后面的括号里的参数为“实参”。

 函数调用

传值调用:单向传递,形参不会改变实参

传址调用:将实参地址传给形参,这时,形参改变,就改变了实参。

函数调用过程

1.在定义函数中指定的形参,在没有被函数调用时,并不占据内存的存储单元,在发生函数调用时才被临时分配空间。

2.函数调用时,实参的值赋给形参。

3.Add函数内,通过形参进行相关运算,通过return将函数值带回主调函数。

4.函数调用完成,形参单元被释放,这时实参的值不会改变。

实参向形参的数据传递是"值传递",只能由实参传给形参,形参的值改变了,对于实参没有影响,由于实参和形参占据两个不同的内存单元,实参不会得到形参的值。

通过函数,交换两个实参的值

#include<stdio.h>
void swap(int* pa, int* pb)
{
	int c = 0;
	c = *pa;
	*pa = *pb;
	*pb = c;
}
int main()
{
	int a = 10;
	int b = 20;
	swap(&a, &b);
	printf("a=%d,b=%d", a, b);
}

结果:a=20,b=10

函数递归

 调用一个函数时,直接或者间接的调用函数本身,称为函数的递归。

1.汉诺塔问题:ABC三个塔,A上面有64个依照大小排好的盘子,现在要求将64个盘子由A移动到C,每次移动一个,且C上盘子必须按照从小到大摆放,输出移动步骤。

#include<stdio.h>
void print(char x,char y)
{
	printf("%c—>%c ",x,y);
}
void move(int i,char a,char b,char c)// 将i个盘子借助b由a移动到c
{
	if (i == 1)
		print(a, c);//递归的终止条件
	else
	{
		move(i - 1, a,c,b); //将a,b两个盘子由A移动到B,借助C
		print(a, c);//将最后大的盘子由A移动到C
		move(i - 1, b, a, c);//将ab两个盘子由B借助A移动到c
	}
}	
int main()
{
	int i = 0;
	printf("输入移动的盘子数目\n");
	scanf("%d", &i);//设i=3
	printf("移动%d个盘子路径是\n", i);
	move(i,'A','B','C');
	return 0;
}

 2.利用递归求n的阶乘

#include<stdio.h>
int fac(int i)
{
	int s = 0;
	if (i == 0)
		s = 1;
	else
		s = fac(i - 1) * i;
	return s;
}
int main()
{
	int i;
	scanf("%d", &i);
	printf("%d", fac(i));
 return 0;
}

 

 3.青蛙跳台阶问题:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个n级的台阶总共有多少种跳法?

 //一个台阶:一种跳法
// 两个台阶: 2种   
// 三个台阶:三个台阶看作一个台阶+两个台阶   3种
//四个台阶:一个台阶+三个台阶      5种

#include<stdio.h>
#include<assert.h>
int fun(int n)
{
	assert(n);
	int s = 0;
	if (n == 1)
		s = 1;
	else if (n == 2)
		s = 2;
	else
		s = fun(n - 1) + fun(n - 2);
	return s;
}
int main()
{
	int i = 0;
	printf("输入台阶数目\n");
	scanf("%d", &i);
	printf("%d", fun(i));
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值