Java-Day05 函数、函数重载、递归函数

目录

1. 函数(function)

1.1 什么是函数

1.2 为什么使用函数

1.3 Java中如何定义函数

1.4 函数调用

1.5 函数的分类

1.6 局部变量

1.7 函数调用的本质

2. 函数重载

3. 函数的递归(recursion):

例题1:求1-100之间所有的数之和

例题2:编写一个程序,打印斐波那契数列某一项的值


1.1 什么是函数

函数就是定义在类中的具有特定功能的一段独立小程序,并能被多次使用。具有名称的特定功能代码的集合。

1.2 为什么使用函数

提高代码的复用性,减少代码的维护成本。

1.3 Java中如何定义函数

权限修饰符 [函数类型修饰符] 返回值类型 函数名([参数类型 形式参数1, 参数类型 形式参数2, ...]){     执行语句;     [return 返回值;] }

注意:在Java中,函数是定义在类中,是类的成员

  1. 权限修饰符:指的就是函数的使用范围(内部和外部)
  2. 函数类型:指的就是函数类型分类,说的就是函数的具体使用场景和场合
  3. 函数名:就是程序员给这一段代码自定义的名称(标识符)
  4. 参数列表:参数列表有若干个 参数类型,参数名... 组成主要用于接收外界传递给函数的一些数据
  5. 函数体:就是那些具有独立功能的代码块
  6. return:仅仅表示结束当前函数,如果有返回值,则函数结束前将返回值返回给调用者
  7. 返回值:指的就是这一具有独立功能的代码块的计算结果,需要传递给外界 配合return
  8. 返回值类型:就是返回值的数据类型(可兼容)

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)。调用堆栈也称为执行堆栈、运行时堆 栈,或者一个机器堆栈,常简称为“堆栈”。当一个方法调用另一个方法时,调用者的活动记录保持不 动,一个新的活动记录被创建用于被调用的新方法。一个方法结束返回到调用者时,其相应的活动记录也被释放。

函数重载(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;     }  }

函数重载,本质是对功能的扩展,不是代码的复用!!!

递归:函数自身调用自身

如果要使用递归:必须有终止条件,没有终止条件的递归就是一个死循环!!

例题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循环去实现这个题目的方法。