day-8 函数
函数:
思想
举例:
ATM机
| //抽象 -- 具体
存钱 取钱 查询 转账 信息修改 退出
|
检测卡片
检测钱
验钞
注:
每个具体问题 --都可以用 一个函数来实现
为什么需要函数?
1.C语言结构化设计的思想,把大问题拆成小问题
2.减少重复劳动 ,提高编程效率
strlen
strcpy
strcat
strcmp
C语言具体的实现:
类型标识符 函数名()
{
声明部分
语句部分
}
返回值的类型标识符 函数名(形式参数) //函数头 ---head
{
函数体 //body
}
返回值的类型标识符 //用来说明 该函数(function)带出来数据的类型
函数名 //起名字的方式和变量名规则一致
形式参数 //是用来接受 实际参数的 变量
函数体 //函数体 就是实现函数具体功能的代码
eg:
实现一个 求两个数 和 的函数
数据输入->函数-->带出结果
//step1: 函数名 ---直接反应函数的功能
sum
add
//step2: 考虑 这个函数,需要用到哪些数据 --- 形式参数
需要用到两个数
形式参数:
类型名 形式参数变量名1,类型名 形式参数变量名2 ...
注意:
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 可以把 表达式的结果,返回给 函数的调用者
函数调用:
语法:
函数名(实际参数);
eg:
sum(1,2);
------------------------
练习:
实现函数,找出两个数中的最大值
功能 -- maxOfTwoNum
形参 -- int a,int b
函数体-- 比较两个数,找出最大
返回值-- 带出 max
注意:
1.返回值类型说明符 可以不写 --- 默认是 int类型
2.返回的结果,与返回值类型说明符,之间类型不一致时,以返回值类型说明符的类型为准
3.形式参数
a.写的时候
int a,int b //对
int a,b //不对
b.用的时候
(1).形式参数 以 实际参数之间
个数相同
类型匹配
一一对应 //第一个实参 就给到第一个形参
4.标识符使用时,一定是先定义,后使用
5.函数可以定义在main函数之前,也可以定义在main函数之后
如果定义在main函数之后,在使用前,必须要有函数声明
函数声明 => 函数头 加 分号
6.如果函数没有返回值,此时返回值类型说明符 可以写成 void //空 -没有
7.如果函数不需要参数,则形参,可以写成void
函数调用的方式:
max(1,2); //1.函数调用数据
int sum = 1+max(1,2); //2.函数调用表达式
printf("ret=%d\n",max(1,2)); //3.函数调用充当了别的函数的参数
练习:
实现函数:
判断一个数,能否被5整除
div5
练习:
判断一个数是不是素数?
练习:
输出n以内的所有素数
n从键盘输入
n
练习:
打印某个月份天数
getMonthDays()
{
isLeapYear();
}
main
{
getMonthDays();
}
注:
1.函数不能嵌套定义 (gnu下支持,但是标准C不支持)
2.函数是可以嵌套调用
函数为什么能够实现层层调用? (后面说)
特殊的嵌套调用:
函数自己调用自己 -- 递归
直接递归
间接递归
递归:
从本质上来说,其实就是循环
这个循环 和 while/do-while/for
递归不能构成死循环!
用递归:
循环:
1+2+3+...+100 累加求和
思路:
递归 //递推+回归
sum(100)
|--sum(99)+100
|--sum(98)+99
|--
...
|--sum(3)+4
|--sum(2)+3
|--sum(1)+2
|--1
总结:
1.递归的思路
第n项 取决第n-1项的问题解决
问题n的解决,需要问题n-1的解决,往前推,直到,有一个明确的结果
2.解决问题
要素
a.递推关系
b.递归结束条件
int sum(int n)
{
}
sum(n)
|--sum(n-1) + n
sum(5)
|
int sum(int n)
{ //n = 4
if (n == 1)
{
return 1;
}else
{
return sum(n-1)+n;
}
}
int sum (int n )
{
//看n有没有到达结束条件
//没有,则继续递归 //递推关系
//有,则递归结束 //递归结束条件
}
练习:
n!
练习:
求斐波拉契数列的第n项
1 1 2 3 5
fibo(5)
|--fibo(4)+fibo(3)
| |--fibo(2)+fibo(1)
| |--1 |--1
|--fibo(3)+fibo(2)
| |--1
|--fibo(2)+fibo(1)
作业:
1.
封装一个函数,获得两个数的最大公约数
5 3
封装一个函数,获得两个数的最小公倍数
5 3
返回值类型: int
参数: int a,int b
函数名: Gcd //greatest common divisor(gcd)
lowest common multiple (LCM)
least common multiple
函数体: 实现思路
2.打印1000以内的所有回文数,用函数实现
应该拆分成两部分
判断回文数
打印回文数。
3. 找一个二维数组中的鞍点,
即:该位置上的元素在该行上最大、在该列上最小。也可能没有鞍点,
1 2 3
4 5 6
7 8 9