目录
函数
构成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;
}