函数
何为函数:为了解决某一特定问题,具有名称的代码集合,可以当做现实中得到一种行为动作!! 过程:n个小过程组成 最好不要超过20行,简化过程实现代码的高度复用。
Java中如何定义函数
访问修饰符 函数返回值的类型 | void 函数名称([参数列表]){ //函数体 //return 返回值 }
Java中函数是属于类的!!必须定义在类中!!所以说函数是类成员,不要写在main函数中,函数不能包含函数。 注意,在main函数中,如果要调用非静态方法, 必须使用构建对象的方式(这个就是后面的面向对象的知识)。
函数的调用:函数无法自己执行,必须要调用。
class TestFun01 {
public static void main(String[] args) {
sayHello();
}
public static void sayHello() {
System.out.println("姓名:xxx");
}
}
函数的分类
- 有参数的函数,调用时必须传递对应的参数(让代码更加灵活),如上面的代码一次执行只能输出一个,故可以用有参函数增加输出的个数:
class TestFun02 {
public static void main(String[] args) {
showInfo("天命", 23, '男');
showInfo("项羽", 21, '女');
}
public static void showInfo(String name, int age, char gender) {
System.out.println("我的名字叫:"+ name);
System.out.println("我的年龄:"+ age);
System.out.println("我的性别:"+ gender);
}
}
执行结果: 2. 无参函数,调用时不需要参数的函数,不灵活。 3. 无返回值的函数:函数名称前是void,没有返回值。
访问修饰符 void 函数名称([参数列表]){ //函数体 //return 返回值 }
- 有返回值的函数:返回什么类型就用什么类型调用!!!
class TestFun03 {
public static void main(String[] args) {
int a = add(5, 8);
System.out.println("8 + 5 = "+ a);
}
public static int add(int x, int y) {
System.out.println("函数开始了……");
return x + y;
}
}
*不能写 string a=add(5,8);*当然,若能自动转换可以用其他数据类型,函数中,如果遇到return关键字,函数立刻返回 执行结果:
- 系统函数:自带的函数内容,可以使用相关工具查找该类型函数,并调用。
- 第三者
- 自定义函数:由程序员自己定义的函数。
局部变量
函数体内定义的变量是局部变量!!!只用于函数体内!!,成员变量是整个类的,而局部变量只属于函数。
判断输入的数字是否为质数:
import java.util.Scanner;
class TestFun04 {
int c = 20;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print(">");
int num = sc.nextInt();
boolean primer = isPrimer(num);
if (primer) {
System.out.println("是质数");
} else {
System.out.println("不是质数");
}
}
public static void test01(int code) {
int a = 10;
a += 100;
System.out.println(a);
a += code;
System.out.println(a);
System.out.println(++code);
}
public static boolean isPrimer(int num) {
for (int i = 2; i < num / 2; ++i) {
if (num % i == 0) {
return false;
}
}
return true;
}
}
执行结果:
函数在内存的调用的本质
首先我们要了解栈与堆, 栈:用于存放变量,当函数执行时,相当于运行的进程,而栈就是计算机内存中存放这些进程,变量的地方。他的存放与释放顺序是先进后出(就像把东西装进瓶子,先进去的被压在底部,故出来是最后出来)设计栈是为了让代码执行完后 继续执行。
假如声明并初始化变量a,把a的值赋给b,如果是队列顺序,a是第一个存入栈的,那么a就会第一个释放,所以不能赋值给b,所以要按照先进后出顺序,不能用队列顺序。
int a = 10;
int b = a;
堆:内存中存放新开辟的对象或数组。 压栈(push):调用函数时就压栈,执行所有代码 放入栈中 弹栈(pop):执行完后离开函数体,释放局部变量 从栈中出去
了解完这些后,我们再看图中,我们先定义函数,则出现压栈情况,然后进行调用时:“Test01()”,test01进行压栈,最后执行并返回(或不返回) ,最后弹栈,释放局部变量。
函数重载(overload)
函数名称相同,函数内参数数据类型不同,参数个数不同,自动匹配对应的函数,返回值的类型要相同(函数重载与返回值无关)
函数重载是所有编程语言都有的吗? 函数重载现象是强数据类型语言(java,c、c++、c#)所持有的现象。弱数据类型语言(javascript、python、ruby 由值决定数据类型)是不具备函数重载,
public static int add(int a , int b){
return a+b;
}
public static int add(int a , byte b){
return a+b;
}
public static int add(int a , int b,int c){
return a+b;
}
函数递归
函数自身调用自身。 优点:分治理念的体现,可以把非常复杂的代码简化 缺点:非常耗费内存,尽量不要超出1000层,递归会不断压栈,可能会导致栈溢出,会触发StackOverflowError 异常!
可设置堆,栈大小,可使用java -x -xss大小。 来调整jvm的栈大小空间 Xms<大小> 设置初始java堆大小 -Xms<大小> 设置最大java堆大小
斐波那契数列:
class TestF {
public static void main(String[] args) {
System.out.println(getFibo2(10));
}
public static int getFibo(int n) {
if (n == 1 || n == 2) {
return 1;
}
return getFibo(n - 1) + getFibo(n - 2);
}
public static int getFibo2(int n) {
int first = 1, second = 2;
int temp;
for (int i = 2; i <= n; i++) {
temp = second;
second = first + second;
first = temp;
}
return first;
}
public static int getStairs(int n) {
if (n == 1) {
return 1;
}
if (n == 2) {
return 2;
}
return getFibo(n - 1) + getFibo(n - 2);
}
}
执行结果
|