java学习第五天----守得云开见月明
1、函数:
(1)定义在类中,有特定功能的一段小程序。
(2)函数的格式:
修饰符 返回值类型 函数名(形参类型 形式参数1,形参类型 形式参数2...)
{
函数体;
reutrn 返回值;
}
A:修饰符 public static
B:返回值类型 程序最终结果的数据类型
C:函数名 其实就是函数的名称,方便我们调用。
D:参数
形参类型 数据类型
形式参数 就是接收实际参数的变量
实际参数 就是实际参与操作的变量(常量)
E:函数体 就是按照正常的逻辑完成功能的代码。
F:返回值 就是程序的最终结果
G:reutrn 返回值 哪里调用程序,return就把结果返回到哪里。
(3)函数的特点:
A:函数与函数之间是平级关系。不能在函数中定义函数。
B:运行特点 函数只有被调用才执行。
(4)函数的调用
A:有明确返回值
a:单独调用 一般没有意义。
b:输出调用 但是如果想拿结果继续操作,就有问题了。所以,不好。
c:赋值调用 推荐方式。
B:void类型
单独调用
(5)函数是怎么结束的?
A:函数其实是关键字return结束的。
B:void程序最后一行默认是return;
(6) 函数的重载:需求:在很多时候我们的功能是相同的,但是参数可能不同。如果起不同的名字,当然是可以的。
但是又由于函数的名字有很重要的意义--见名知意。sum---求和
所以很多时候,我们必须用一个有意义的名字。在这种情况下,java就提供了一种机制,函数重载
特点:
函数名相同,参数列表不同。对应个数和类型
如果个数不同,函数值类型相同----是重载
如果个数相同,函数值类型不同----是重载
如果个数相同,函数值类型相同----不是重载是报错。
与返回值类型无关,函数值类型可以不相同。
注意:
永远建议,写的什么类型的形式参数,就用什么类型的实际参数调用。
class FunctionDemo4
{
public static void main(String[] args)
{
System.out.println(sum(10,20));//程序自己会根据函数列表匹配函数,
//是sum(int a,int b)而不是(int a,int b,int c)
System.out.println(sum(10,20,30));
}
//求两个数的和
public static int sum(int a,int b)
{
return a+b;
}
//求三个数的和
public static int sum(int a,int b,int c)
{
return a+b+c;
}
}
2:数组
(1)数组是存储同一种类型的多个元素的容器。
(2)好处:数组中的元素会被自动从0开始编号,方便我们获取。
(3)格式:
数组格式:
A:元素类型[] 数组名 = new 元素类型[元素个数或数组长度];
int[] arr = new int[3];
B:int arr[] = new int[3];
C:int[] arr = new int[]{1,2,3};D:int[] arr = {1,2,3};
推荐A和D。
例如:
public static void main(String[] args)
{
int[] arr = new int[5];
/*
数据类型:
基本类型:4类8种(存在栈里)
引用类型:类,接口,数组(存在堆里)。
左边:
int:表示数据类型
[]表示这是一个数组
arr:数组名字。
右边:
new:申请内存空间的。
int 表示数据类型
[] 表示这是一个数组
5 表示数组长度。
*/
3、内存结构:
java程序在运行时,需要在内存中分配空间。为了提高运算效率,有对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
栈内存:存储变量,或者方法的执行。用于存储局部变量,当数据使用完,所占空间会自动释放。
栈的效率高。
堆内存:所有new出来的。
1》 数组和对象,通过new建立的实例都存放在堆内存中
2》 每一个实例都有内存地址值,本身是一个十进制,显示的时候是16进制。
3》实例中的变量都有默认初始值,整数:0,浮点数:0.0,字符型:“\u0000”,布尔型:false;
4》实例不在被使用,会在不确定的时间内被垃圾回收器回收。
但数据使用完毕,超出了作用域,他就在自动从内存中消失。
方法区:方法,String常量池,静态区(面向对象)。
本地方法区:跟系统相关的方法,因为java语言不能直接操作系统,是有java虚拟机来操作的,这些方法是c或者c++获取。
寄存器
寄存器:由CPU执行
局部变量:定义在方法中或者方法声明中的形式参数都叫局部变量。 与其相对应的是成员变量。
例如:class ArrayDemo4
{
public static void main(String[] args)
{
int[] arr = new int[3];
arr[0]=1;
arr[1]=2;
arr[2]=3;
int[] arr2 = arr;
arr2[1] = 10;
System.out.println(arr[1]);// 10
System.out.println(arr2[2]);// 3
/*
分析:
首先在栈中定义arr,int[] arr = new int[3];上面这个语句表明需要在堆中定义一个3维数组,然后都存入默认的值0,
arr相当于一个指针,指向数组的首地址即arr[0]的地址,因此在栈中存放的是首地址。
当定义int[] arr2在栈中定义,然后int[] arr2 = arr;将arr的首地址给了栈中的arr2,即栈中的arr2也指向了arr的首地址。
当进行arr2[1] = 10;操作后,将堆中的arr2[1]和arr[1]改变了值。
arr2[2]=arr[2]=3;
*/
}
}
总之,int[] arr 是在栈中操作的,而new的过程是在堆中操作的,即arr的值是存在堆中的,栈种的arr指向了堆中的首地址。
4、数组操作的常见问题:
A:数组越界异常,你访问了不存在的索引。
int[] arr = {1,2,3,4,5};
System.out.println(arr[5]);/
B:空指针异常,一个实例(对象)已经不存在了,还要访问
arr = null;//null是空常量,空常量可以赋值给引用类型常量,表示这个引用没有指向任何东西。
程序:class ArrayDemo3
{
public static void main(String[] args)
{
arr = null;//null是空常量,空常量可以赋值给引用类型常量,表示这个引用没有指向任何东西
System.out.println(arr[4]);
}
}
以下图片为两段程序的实行过程
4、二维数组
二维数组其实就是元素是一个一维数组,
二维数组格式:
方式1:
int[][] arr = int[3][2];
定义了名称为arr的二维数组, 二维数组中有3个一维数组,每一个一位数组中有2个元素
一维数组的名称分别为arr[0],arr[1],arr[2];
给第一个一维数组的1索引位赋值为78写法是:arr[0][1] = 78;
方式2:
int[][] arr = int[3][];
非规则的矩形,二维数组有3个一维数组,然后对这三个一维数组分别初始化:
arr2[0] = new int[3];
arr2[1] = new int[2];
arr2[2] = new int[1];
方式3:
int[][] arr = {{3,8,2},{2,7},{9,0,1,6}};