目录
1. 函数(function)
1.1 什么是函数
函数就是定义在类中的具有特定功能的一段独立小程序,并能被多次使用。具有名称的特定功能代码的集合。
1.2 为什么使用函数
提高代码的复用性,减少代码的维护成本。
1.3 Java中如何定义函数
权限修饰符 [函数类型修饰符] 返回值类型 函数名([参数类型 形式参数1, 参数类型 形式参数2, ...]){
执行语句;
[return 返回值;]
}
注意:在Java中,函数是定义在类中,是类的成员
- 权限修饰符:指的就是函数的使用范围(内部和外部)
- 函数类型:指的就是函数类型分类,说的就是函数的具体使用场景和场合
- 函数名:就是程序员给这一段代码自定义的名称(标识符)
- 参数列表:参数列表有若干个 参数类型,参数名... 组成主要用于接收外界传递给函数的一些数据
- 函数体:就是那些具有独立功能的代码块
- return:仅仅表示结束当前函数,如果有返回值,则函数结束前将返回值返回给调用者
- 返回值:指的就是这一具有独立功能的代码块的计算结果,需要传递给外界 配合return
- 返回值类型:就是返回值的数据类型(可兼容)
1.4 函数调用
当函数定义完成后,不会自己执行,需要通过调用来执行
函数名称([实际参数列表])
如下实现了一个打印Hello的函数:
public class Function {
public static void main(String[] args) {
// 调用函数
printHello();
}
// 定义一个函数
// static 关键字的作用是将函数提前加载到内存中
public static void printHello() {
System.out.println("Hello");
}
}
1.5 函数的分类
1. 通过函数是否存在参数
- 无参函数
- 有参函数
2. 函数是是否需要返回计算结果
- 无返回值
- 有返回值
1.6 局部变量
定义在函数内部的变量,叫做局部变量,局部变量的作用域只在当前函数中有效
注意:在Java中没有全局变量,main函数中的变量也是局部变量,只是比较特殊
作用域还是main函数本身,但是声明周期是比较长
public class Function {
public static void main(String[] args) {
// 调用函数
printHello();
System.out.println(a); // 错误: 找不到符号
}
// 定义一个函数
// static 关键字的作用是将函数提前加载到内存中
public static void printHello() {
int a = 10;
System.out.println("Hello");
}
}
在上述的代码中,函数printHello()中的变量就是局部变量。当在主函数中调用时,会报错。
1.7 函数调用的本质
函数本质是一个对象,存储在对中,当调用时,会临时的压入栈中(push),等调用完成后,函数被弹出栈(pop)。所以函数调用就是瞬时操作。
调用函数 ==> 函数压栈 ==> 函数调用完 ==> 函数出栈
函数的运行原理:
每当调用一个方法时,系统会创建一个活动记录(也称为活动框架),用于保存方法中的参数和变 量。活动记录置于一个内存去榆中,称为调用堆栈(call stack)。调用堆栈也称为执行堆栈、运行时堆 栈,或者一个机器堆栈,常简称为“堆栈”。当一个方法调用另一个方法时,调用者的活动记录保持不 动,一个新的活动记录被创建用于被调用的新方法。一个方法结束返回到调用者时,其相应的活动记录也被释放。
2. 函数重载
函数重载(overload):至少两个或者更多函数,函数名称相同,但是参数的个数或者类型不同,从而在调用的时候,可以通过传参确定要调用的函数
public class OverLoadTest {
public static void main(String[] args) {
System.out.println(add(10, 20)); // 30
byte a = 10;
System.out.println(add(a, 10)); // 20
System.out.println(add(10)); // 110
}
public static int add(int x, int y) {
return x + y;
}
// 错误: 已在类 OverLoadTest中定义了方法 add(int,int)
// public static int add(int a, int b) {
// return a + b;
// }
public static int add(byte a, int b) {
return a + b;
}
public static int add(int a) {
return a + 100;
}
}
函数重载,本质是对功能的扩展,不是代码的复用!!!
3. 函数的递归(recursion):
递归:函数自身调用自身
如果要使用递归:必须有终止条件,没有终止条件的递归就是一个死循环!!
例题1:求1-100之间所有的数之和
public class RecursionTest {
public static void main(String[] args) {
int s = sum(100);
System.out.println(s); // 5050
int n = sum1(100);
System.out.println(s); // 5050
}
public static int sum(int n) {
return n * (1 + n) / 2; // 等差数列
}
public static int sum1(int n) {
return n + sum(n - 1); // 递归
}
}
除次之外,我们还可以使用for循环去实现。
再如,
例题2:编写一个程序,打印斐波那契数列某一项的值
import java.util.Scanner;
public class RecursionTest1 {
// 输入一个数n,输出斐波那契数列的第n项值
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("请输入项数:");
int n = scan.nextInt();
int result = fibonacci(n);
System.out.println(result);
fibonacci1(n);
}
public static int fibonacci(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
public static void fibonacci1(int n) {
int frist = 0;
int second = 1;
int three = 0;
for (int i = 2; i <= n; i++) {
three = frist + second;
frist = second;
second = three;
}
System.out.println(three);
}
}
函数fibonacci是一个递归函数,而fibonacci1函数是一个使用for循环去实现这个题目的方法。