前言
函数
文章目录
一、关键点
- 理解函数的执行顺序;
二、知识点
1、函数编写
- 组成
- 修饰符;
- 返回类型;
- 函数名;
- 函数参数(0 个或多个);
- 函数体(具体的逻辑);
- 返回值(重点,执行这个函数得到的结果)
- 调用
- 函数名(参数);
- 函数实参
- 函数调用时传入的实际参数,实参是形参的初值;
- 函数形参
- 定义函数时的参数,需声明参数类型;
- 函数的形参和实参的名字可以相同也可以不同;
- 调用函数执行顺序
- 第一步:将实参赋值给形参 ;
- 第二步:将控制权转移给被调用函数,此时,暂停主调函数,被调函数开始执行;
- 第三步:被调函数执行完成,返回调用函数,继续执行调用函数;
2、函数参数传递方式
1)值传递
- 八大基本数据类型和 String 类型 等采用的均为值传递;
- 函数调用时, 实参的初始值拷贝给形参,拷贝完成,形参和实参为两个独立的个体,互不影响,对形参的修改不会影响实参的初始值;
2)引用传递
-
除 String 以外的其它非基本数据类型的对象,修改函数内部形参的值会影响函数外实参的值;例如 数组、StringBuilder;
-
形参改变原来实参的地址值,实参也会发生变化;形参不改变原来实参的地址值,实参不会发生变化;
// 实参地址sb拷贝给形参str,str与sb指向同一段内存空间,对str指向内存空间的内容进行修改,sb指向的内容也会相应发生改变 public class Main { private static void f(StringBuilder str) { str.append("Hello world"); } public static void main(String[] args) { StringBuiler sb = new StringBuiler(""); f(sb); System.out.println(sb); // HelloWorld } }
// 实参地址sb拷贝给str,str与sb指向同一段内存空间,new会生成一段新的内存空间赋值给str, // str与sb指向的两段不同的内存空间,修改str指向内存空间的内容,sb指向内存空间的内容不会发生改变 public class Main { private static void f(StringBuilder str) { str = new StringBuilder("Hello world"); // 采用直接赋值的方式 } public static void main(String[] args) { StringBuiler sb = new StringBuiler(""); f(sb); System.out.println(sb); // 空字符串 } }
3)总结
- 值传递和引用传递本质都是传值,引用传递传的是地址,地址也是一个值;
- 若传递的变量类型为对象,其真实值存储在地址上;基本变量类型存储的不是地址,是真实值;
3、函数返回值
- void、基本数据类型、数组、字符串或对象;
4、变量作用域
1)局部变量
- 定义在函数内部,只能在函数内访问,函数外不能访问;
![](https://img-blog.csdnimg.cn/direct/f1cd99e824d04e6288b07a9449610f5a.png)
2) 全局变量(成员变量)
- 全局变量即 Java 中的成员变量,定义在类中,类的所有成员都可以访问;
- 用于解决局部变量的只能在函数内部访问的弊端,可以实现在多个函数中进行访问,函数内对成员变量修改,函数外也会修改;
3)局部变量与成员变量重名
-
局部变量与成员变量重名时,函数内优先使用的是局部变量;
public class Main { private static int x = 4; private static void f1() { int x = 3; System.out.println(x); // 3,使用的是局部变量的x } private static void f2() { System.out.println(x); // 4,使用的是成员变量 x = 10; // 10,修改成员变量 } private static void f3() { System.out.println(x + 1); // 11,使用的是成员变量 } }
5、return 语句
1)作用
- 结束当前执行的函数并将控制权返回到调用函数的地方;
2)形式
-
无返回值:
return;
函数返回值类型为 void;返回 void 的函数不要求非得有 return 语句,因为在这类函数的最后一句后面会隐式地执行 return。作用为在函数执行某个位置结束函数,类似于循环中的 break 语句; -
有返回值:
return expression;
表达式返回结果类型要与函数返回值类型一致;
3)注意
- 只要函数的返回类型不是 void,则该函数内的每个分支(每种情况)都必须有
return
语句,且每条return
语句(每种情况)都必须返回一个值。; return
语句返回值的类型必须与函数的返回类型相同,或者能隐式地转换函数的返回类型;// 这段代码会报错,因为函数有返回值类型的话,函数中每种情况都必须要有返回值 public class Main { private static int max(int a, int b) { if (a > b) return a; // a <= b 的情况缺少return语句 } public static void main(String[] args) { System.out.println(max(3, 4)); } } // 修改后的正确代码:无论什么情况必须要有返回值 public class Main { private static int max(int a, int b) { if (a > b) return a; return b; // 增加其它情况的返回值 } public static void main(String[] args) { System.out.println(max(3, 4)); } }
// 函数重载:同一个函数名可以出现多次,只要函数名与参数列表拼在一起不同会代表不同的函数;在函数调用时,会根据实参类型来匹配到与其最合适的函数来执行 public class Main { private static int max(int x, int y) { if (a > b) return a; return b; } private static double max(double x, double y) { if (a > b) return a; return b; } public static void main(String[] args) { System.out.println(max(3.0,4.0)); // 调用第二个max函数 System.out.println(max(3,4)); // 调用第一个max函数 } }
6、函数递归
- 本质为函数调用;
- 函数里面可以调用其它函数。特殊的调用方式为函数里面调用自己本身,被称为递归;
- 关键点:画递归搜索树