Java笔记day01--函数入门

Java学习笔记整理


在学习这一部分之前,需要明确几个问题:
1.什么是函数?
2.Java中怎么定义函数?
3.Java中怎么调用函数?
4.函数调用的内存模型分析(压栈)-- 内存的分析
5.函数的分类:
(1)返回值
(2)参数
6.值传递和引用传递问题
7.函数重载
8.递归的概念


1.什么是函数
函数:具有名称为了实现某一特定功能的代码的集合。封装代码,提高代码的复用性。

2.Java中怎么定义函数?

语法结构:

		访问修饰符 static 返回值的类型 函数名称([参数名称]){
			// 函数体

			[return 返回值;]
		}

函数必须定义在类里,不能在main函数里


3.函数的分类
(1)void表示没有返回值;如果需要返回值,则需要在void位置写明返回值类型并在参数名称在中声明参数类型。
(2)如果不调用,函数不会执行;调用函数时如有参数,需要在括号内写明。

4.函数调用
举例:
(1)say函数:打印一句话
(2)showInfo函数:显示自己的基本信息

public class Test{
	// main函数是程序的入口,必须这样写
	public static void main(String[] args){
		// 静态(static)函数中只能调用静态函数,静态函数中,无法调用非静态函数
		// 调用函数
		say();
		showInfo();

	}
	// 定义了一个say的函数
	public static void say() {
		System.out.println("hello,I`m a function.");
	}

	static void showInfo() {
		System.out.println("我叫ABC");
		System.out.println("456");
	}

}

在这里插入图片描述
如果函数增加了参数,在主函数内调用时也要增加相应的参数。

public class Test{

	public static void main(String[] args){
		showInfo("王力宏",20,"陕西西安");
	}

	static void showInfo(String name,int age,String address) {
		System.out.println("我叫"+ name);
		System.out.println("我今年"+ age +"岁");
		System.out.println("我住在"+ address);
	}

}

在这里插入图片描述


5.Java的函数分类
判断方式:通过是否存在参数分为有参函数和无参函数,是否存在返回值分为有返回值的函数和无返回值的函数。
(1)加法运算

public class Test{

	public static void main(String[] args){
		int res = add(10,50);
		System.out.println(res);
	}

	public static int add(int x,int y) {
		// 函数中,执行到return关键字,函数直接返回
		return x + y;
	}

}

在这里插入图片描述
(2)判断质数

import java.util.Scanner;

public class Test{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个数:");
		int num = sc.nextInt();
		boolean flag = isPrimer(num);
		
		if (flag) {
			System.out.println("该数是质数");
		} else {
			System.out.println("该数是合数");
		}
	}

	public static boolean isPrimer(int num) {
		for (int i = 2; i < num; i++) {
			if (num % i == 0) {
				return false;
			}
		}
		return true;
	}

}

在这里插入图片描述
在函数中,定义的参数可以和主函数中定义的参数使用相同的字符,它们分属不同的作用域。


6.内存的调用分析
栈stack:一种线性结构,先进后出FILO(后进先出LIFO),
堆heap:内存中最大的区域,函数存储在堆里
代码区:
数据区:
在这里插入图片描述int a = 10; add(a,20);
在栈中创建一个变量a,存储一个数据10;在堆中储存函数add。同时,在栈中储存着一个add变量,里面储存着函数add的地址,即栈中的add指向内存中的函数add。当函数调用时,栈中的add找到函数,将函数中的程序压到栈中,这个过程即压栈的过程,压栈(put)是将堆里储存的函数在栈中执行的过程。当函数调用完之后,会出栈(弹栈pop)。

public class Test{
	public static void main(String[] args){
		System.out.println(a);
	}

	public static int add(int x,int y) {
		int a = 10;
		return x + y;
	}

}

Q:函数中定义的变量,主函数中能否调用?
A:在以上程序中,函数中定义了一个变量a,数据为10,它是在堆中定义的,属于局部变量。当执行压栈的过程,int a = 10从堆中进入栈,函数调用完成后,这部分内存随着弹栈被回收,因此主函数中不能调用该变量。

在上面的程序中提到了局部变量这一概念,局部变量是定义在函数内部的变量,必须初始化(赋值),否则无法使用。


7.函数重载
重载(overload)是多个函数形成的一种关系,函数名称相同参数的类型或者参数的个数不同。该现象只存在于强数据类型语言中,弱数据类型语言中不存在(如:JavaScript、PHP、Python)。

public static int add(int x,int y) {
	return x + y;
}

public static int add(int x,int y,int z) {
	return x + y + z;
}

以上两个函数构成重载,我们可以套入参数测试一下:

public class Test{
	public static void main(String[] args){
		System.out.println(add(5,4));
	}

	public static int add(int x,int y) {
		System.out.println(111);
		return x + y;
	}

	public static int add(int x,int y,int z) {
		System.out.println(222);
		return x + y + z;
	}
}

输出结果:
在这里插入图片描述
如果将参数由两个改为三个:

public class Test{
	public static void main(String[] args){
		System.out.println(add(5,4,10));
	}

	public static int add(int x,int y) {
		System.out.println(111);
		return x + y;
	}

	public static int add(int x,int y,int z) {
		System.out.println(222);
		return x + y + z;
	}
}

输出结果:
在这里插入图片描述

public static int add(int x, int y) {
	return x + y;
}

public static int add(int y, int x) {
	return x + y;
}

以上两个函数参数类型和个数相同,不构成重载。

public static int add(int x, int y) {
	return x + y;
}

public static double add(double a, int b) {
	return x + y;
}

以上两个函数,函数名称相同,参数类型不同,构成重载。

public static double add(double a, int b) {
	return x + y;
}

public static double add(int b,double a,) {
	return x + y;
}

函数名相同,参数类型不同,构成重载。

需要注意,函数重载和重写是不同的概念。


8.递归的使用
递归(recursive)是函数自身调用自身的现象,是一种分治思想的体现。
递归的必要条件:
(1)函数必须自身调用自身。
(2)递归必须要有终止条件;若无终止条件,递归是一个死循环----调用函数的过程中,因为递归的关系,每次执行完函数的程序之后,函数在栈空间内再次调用自身,直达栈空间消耗完为止,JVM抛出StackOverflowError异常。
以下是递归的一个例子:

public class Test{
	public static void main(String[] args){
		int sum = getSum(100);
		System.out.println("1~100的和是"+ sum);
	}
	
	// 使用递归完成1 ~ 100的和
	public static int getSum(int num) {
		if (num <= 1) {
			return 1;
		}
		return num + getSum(num - 1);
	}
}

在这里插入图片描述
将参数改为20000,执行程序:
在这里插入图片描述
栈空间消耗完了,报错。
栈空间可以修改,先编译,然后

>java -Xss空间大小 文件名

在这里插入图片描述
(3)递归实例
斐波那契数列:从第三个数开始,每一个数的值是前两项之和。
使用递归,求第N项的对应的值(n > 2)
要求:第一项是1, 第二项的值是2。

import java.util.Scanner;

public class Test{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入项数:");
		int num = sc.nextInt();
		int res = Fibonacci(num);
		System.out.println(res);
	}

	public static int Fibonacci(int n) {
		if (n == 1) {
			return 1;
		}

		if (n == 2) {
			return 2;
		}
		return Fibonacci(n - 1) + Fibonacci(n - 2);
	}
	
}

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值