函数
为什么需要函数?
1.c语言结构化设计的思想,把大问题拆成小问题
2.减少重复劳动,提升编程效率
函数具体的实现
返回值的类型标识符 函数名(形式参数) // 函数头---head
{
函数体 //body
}
返回值的类型标识符 // 用来说明 该函数带出来数据的类型
函数名 // 起名字的方式和变量名规则一致
形式参数 // 是用来接受实际参数的变量 --- 类型名形式参数变量名1,类型名形式 参数变量名2...
函数体 // 函数体就是实现函数具体功能的代码
eg:
实现一个 求两个数 和 的函数
数据输入->函数-->带出结果
//step1: 函数名 ---直接反应函数的功能
sum
add
//step2: 考虑 这个函数,需要用到哪些数据 --- 形式参数
需要用到两个数
形式参数:
类型名 形式参数变量名1,类型名 形式参数变量名2 ...
a.写的时候 必须 int a,int b
b.用的时候 形式参数和实际参数之间 要个数匹配 类型匹配 一一对应
注意:
1.每一个形式参数,都有自己的 类型名
int a,int b //形式参数的定义
int a,b //表示定义了两个int型变量a 和 b
//step3:实现函数体 ---函数具体功能代码
int result = a + b;
//step4:要带出怎么结果 --- 函数返回值的设计
带出计算的结果
int sum(int a,int b)
{
int result = a + b;
return result;
}
如果要带出结果:
return 语句 //表示,从函数中返回(就是函数结果)
return 表达式; //return 可以把 表达式的结果,返回给 函数的调用者
注意:
1.每一个形式参数,都有自己的类型名
int a,int b //形式参数的定义
int a,b //表示定义了两个int型变量a和b
2.返回值类型说明符可以不写,不写的时候默认int类型
3.返回的结果,与返回值类型说明符之间类型不一致时,以返回值类型说明符的类型为准
4.形式参数
形式参数与实际参数之间 个数相同 类型匹配 一一对应
5.标识符使用时,一定是先定义,后使用
6.函数如果定义在main函数之后,在使用前,必须要有函数声明
函数声明 => 函数头加分号
7.如果函数没有返回值,此时返回值类型说明符可以写成void,如果函数不需要参数,则形参可以写成void
1.函数不能嵌套定义(gnu下支持,但是标准c不支持)
2.函数是可以嵌套调用
函数调用
语法:
函数名(实际参数);
eg:
sum(1,2);
特殊的嵌套调用: 函数自己调自己--递归
递归:本质上说,其实就是循环,
这个循环和while/do-while/for区别在于
递归不能构成死循环 会发生内存不够用的情况
递归// 递推 +回归
1.递归的思路
第n项取决于第n-1项的问题解决
问题n的解决,需要问题n-1的解决,往前推,直到,有一个明确的结果
2.解决问题
a.递推关系
b.递归结束条件
int sum (int n )
{
//看n有没有到达结束条件
//没有,则继续递归 //递推关系
//有,则递归结束 //递归结束条件
递归的过程,实际上是函数的调用,而函数调用需要 使用 栈空间(内存空间)
栈:
1. 是一种数据结构 FILO (First In Last Out)
2. 内存上的一块空间
3. 大小肯定是有限的
4. 可以存放函数调用数据
5. 局部变量(自动变量)
自动申请,自动释放
32位 --- 4G内存空间
32位 地址总线 32位
2^32 => 2^10 * 2^10 * 2^10 *2^2
1024 1024 1024 4
1K 1M 1G
程序 = 数据 + 代码
经典的递归模型--汉诺塔:
问题n
|--问题n-1 与 n
|--问题n-2
|---
...结束条件
hanoi(64)
|---hanoi(63)
|---hanoi(62)
|---
...
hanoi(1)
思路:
//hanoi(n)
//n = 3
1. 将n-1格盘子, 从 A 起始柱 移动 B 辅助柱子
2. 将第n格盘子,从A移动到C
3. 再将n-1盘子,从B 移动到 C
//n = n-1 => 2
1. 将n-1格盘子, 从 A(起始柱子) 移动 C 辅助柱子
2. 将第n格盘子,从A (起始柱子) 移动到B (目标柱子)
3. 再将n-1盘子,从B 移动到 C
#include<stdio.h>
2
3 void move(int n,int pole1,int pole2)
4 {
5 static int step = 1;
6 printf("%03d:[disk %d] :%c --> %c\n",step++,n,pole1,pole2);
7 }
8
9 void hanoi(int n,int A,int B,int C)
10 {
11 if (n==1)
12 {
13 move(n,A,C);
14
15 }else
16 {
17 hanoi(n-1,A,C,B);
18 puts("-------");
19 move(n,A,C);
20 puts("-------");
21 hanoi(n-1,B,A,C);
22 }
23 }
24 int main(void)
25 {
26 int n = 0;
27 printf("Input numbers of disk:");
28 scanf("%d",&n);
29
30 hanoi(n,'A','B','C');
31 return 0;
32 }