第五节:函数和数组

本文详细介绍了函数的概念、定义原则及使用细节,包括函数重载等内容。同时深入探讨了数组的定义、内存分配、常见问题及应用案例,如遍历、求和等。此外还讲解了二维数组的相关知识点。

目录

一、函数的概念

1.1函数概念

1.2定义函数原则

1.3函数的使用细节

二、函数的重载

2.1重载的概念(同类同名不同列)

2.2函数命名规范

三、数组的定义

3.1数组的概念

3.2数组定义格式

3.3数组的好处

四、数组的内存图解

4.1、Java的内存分配

4.2、数组的内存分配

五、数组的常见问题

5.1、数组角标越界异常

5.2、空指针异常

六、数组的应用(遍历、求和、最值)

6.1、数组的第二种定义格式

6.2、遍历数组

6.3、案例:数组求和

6.4、案例:数组求最值

6.5、将数组转成字符串

6.6、数组反转

6.7、数组的使用思想

七、二维数组

7.1、二维数组定义

7.2、二维数组内存图解

7.3、二维数组的其他定义格式

7.4、二维数组遍历


一、函数的概念

1.1函数概念

 函数

        也可以称为方法。它表示的是一段可以独立运行的代码,并且具有独立功能。当在程序中需要使用的时候可以通过函数(方法)的名字去调用

格式:

函数的修饰符  函数的返回值类型  函数的名( 接收的参数类型  参数名 ,  接收的参数类型  参数名  ....)

{

函数体代码;//具体完成相应功能的代码。

}

书写位置

它必须在类的大括号中,不能写在main方法里面,要和main方法在关系上属于并列关系,我们自己定义的函数(方法)和main方法没有先后次序。

实例:

定义函数的细节:

函数的修饰符:目前针对函数的修饰符,我们先照抄main方法。

返回值类型:当我们在程序封装了一段独立的代码之后,如果这段代码运行完,需要把一个具体的结果返回给调用者,这时当前这个函数的返回值类型就需要和返回的那个数据保持一致。如果这个函数调用完之后,不需要给调用者返回任何数据,这时函数的返回值类型必须写void

函数的名:它就是前面学习的标识符。我们给独立代码命名需要遵守标识符的规则。

参数列表:当定义一个功能的时候,需要接受调用者传递进来的数据时,就需要在定义函数的时候,书写对应的参数,而参数的类型,就是前面学习的定义的变量。如果不需要接受参数,这时小括号中的参数可以省略,但是小括号不能省略。

函数体:就是在函数的大括号中书写代码,这里的代码和以前学习时在main方法中写的代码没有区别,以前在main方法中可以写的任何代码,都可以在自己定义的函数体中书写

原则:

在书写代码的时候,每段代码如果是一个独立的功能,这时需要把这些代码单独的抽离到一个函数中,不要把所有代码全部书写在main方法中。

1.2定义函数原则

定义函数的原则:

  1. 遵守函数的定义格式。
  2. 定义函数的时候,一定要仔细去分析需求,确定函数要不要返回值
  3. 定义函数的时候,确定档期这个函数要不要接收参数

当定义功能的时候,数据并不是自己功能中产生的,而是需要调用者传递进来,然后根据传递的参数进行其他的操作。这时一定要接收对应的参数。

1.3函数的使用细节

1、函数的返回值问题:

一般在我们定义函数的时候,肯定是先有需求,然后需要根据这个需求进行分析,在分析的过程中,如果需要把函数运行之后的结果告诉调用者,这时函数必须有返回值,并且在函数体中必须书写return语句,把具体的值返回。

如果函数运行完之后,不需要把结果告诉调用者,这时函数不需要返回任何数据,那么在函数体中可以不写return数据。

问题:在一个函数中能不能有多个return语句?

可以。但是只能执行一个

问题:在一个函数中能不能返回多个值?

不能。在一个函数中,一个return语句,只能返回一个值。

2、参数问题:

定义功能的时候,需要接收参数,这时在功能上一定要定义变量,然后接收具体的参数,这时参数的类型必须和传递的数据一定要保持一致。如果不需要接受数据,就可以省略参数。

 

3、问题:当一个函数没有返回值的时候,可以书写return语句吗?

可以。一个函数没有返回值,返回值类型一定是void ,但在函数中可以书写return语句,这时的return后面直接写分号,不要接任何数据。

return ; 这样的return,只是为快速的结束函数。

二、函数的重载

2.1重载的概念(同类同名不同列)

重载:函数的重载,要求必须在同一个类(程序)中,有多个同名的函数,它们的参数列表不同,这时我们称为函数的重载。

注意:

  1. 要求必须在同一个类中(程序)。
  2. 要求函数的名称必须相同
  3. 要求函数的参数列表必须不同

参数列表不同,主要针对的参数的个数,类型,顺序不同。

由于函数可以在同一个类出现重载的现象,因此在调用的时候,具体应该执行哪个函数,需要根据调用者传递的实际参数决定。

2.2函数命名规范

函数名的规范:

类名:多个单词每个单词首字母大写。

变量名:多个单词,从第二个单词开始,首字母大写。

函数名:它的书写规则和变量名一致。

getSum(  ) 这是一个求和的函数

printNumber(  ) 打印数字

printArray( ) 打印数组

变量名的后面是不会加小括号的,

 count() count函数名  count 变量名

三、数组的定义

3.1数组的概念

数组:数组表示的一串连续的存储空间。每个空间中都可以保存一个数据。当我们需要操作的时候,不要去面对单个空间,而直接面对这个整体的连续的存储区域

3.2数组定义格式

第一种定义格式:

格式:

数组中保存的数据类型[] 数组的名 = new 数组中保存的数据类型[ 开辟的连续空间个数 ];

数据类型[] 数组名 = new 数据类型[长度] ;

第二种定义格式:

在定义数组的时候,如果已经知道数组中的具体数据,这时可以在定义数组的时候直接书写具体的数据。

格式:

数据类型[] 数组名 = {值,值,值.......};

int[] arr = {11,22,33,44,55,66};

 

//定义变量:

数据类型  变量名 = 值;

int a = 123;

//定义数组:

int[] arr = new int[4];  在内存中一次开辟4个连续的空间,每个空间都是int类型,并且这些空间中保存的数据也必须是int类型。

3.3数组的好处

好处

  1. 可以一次性开辟出更多的空间。
  2. 可以对多个空间进行统一的管理。
  3. 数组定义好之后,每个数组的空间中都有一个唯一的编号(索引index ,下标,角标)。我们在操作数组的时候,需要通过该数组的统一的名称和对应的下标来操作数组中每个空间。
  4. 数组的下标是从0开始,到长度-1结束。如果操作的下标不再这个范围中,程序报错。
  5. 在数组中有个属性length,可以获取到当前数组的长度

 

注意

数组可以按照如下方式定义:(但是没有第一种常用)

数据类型 数组名[] = new 数据类型[长度];

 

例如: double arr[] = new double[6];

 

四、数组的内存图解

4.1、Java的内存分配

当我们在dos窗口输入了java class文件名 回车之后,启动JVM。

JVM把内存划分成5片区域:

栈内存:栈内存主要是用来运行函数的,在函数中定义的所有变量,都会在这个内存开辟空间。

在栈内存中定义的变量,不初始化,是不能直接使用的。

 

堆内存:在程序中使用new 关键字创建出来的所有东西,都会保存在堆内存中。

堆内存中开辟的空间,不赋值,都会有默认的初始化数据。

整数:默认是0

小数 默认0.0.

boolean 默认是false

char 默认是 ‘\u0000’

 

方法区:JVM在加载class文件的时候,所有的class文件就要加载在这个内存中。

 

本地方法区:主要是保存native关键字标注的方法

寄存器:是给CPU使用的。

4.2、数组的内存分配

 

 

数组的简单操作:

我们需要通过数组的总名称 引用变量空间,然后通过这个引用空间中的地址,再去找到堆内存中的连续的空间,然后才能准确的去操作数组。

 

给数组的每个空间赋值:

数组名[ 下标 ] = 值;

 

我们定义的数组名空间:

它是一个特殊的内存空间,它中只能保存某个数字在堆中的内存地址。而不能像前面学习普通变量一样来保存普通的常量。

数组名空间保存某个数组的地址,而数组的每个真实空间保存具体的普通常量数据。

五、数组的常见问题

5.1、数组角标越界异常

 

ArrayIndexOutOfBoundsException:

当我们在操作数组的时候,指定的数组的下标,超越的数组空间的真实下标之后,就会发生这个问题。

在操作数组的时候,一定要保证下标在0~长度-1之间。

5.2、空指针异常

 

 

NullPointerException:空指针异常。

在当前的程序中使用一个引用变量,但是这个引用变量并没有指向一个真实的内存空间,而导致这个问题。

当程序中发生上述这个异常的时候,这时应该去看当前这行代码中哪里使用的引用变量,肯定是这个引用变量不指向具体的某个堆中的内存地址,导致null的发生。

在Java中当被new出来的堆中的内存,没有任何一个引用指向它的时候,这时它就是一个垃圾JVM就使用垃圾回收器把当前这片内存清理。

int[] arr = new int[5];

int[] arr2 = arr;

arr = null;

 

问:堆中有垃圾吗?

没有,因为上述代码,先有2个引用变量指向数组,后面虽然把一个引用赋值null,但还有一个引用指向数组,这时是没有垃圾的。如果一个内存空间没有任何引用指向,这时这片内存才会变成垃圾。

六、数组的应用(遍历、求和、最值)

6.1、数组的第二种定义格式

格式:在定义数组的时候,如果已经知道数组中的具体数据,这时可以在定义数组的时候直接书写具体的数据。

数据类型[] 数组名 = {值,值,值.......};

int[] arr = {11,22,33,44,55,66};

 

6.2、遍历数组

class ArrayTest2

{

       public static void main(String[] args)

       {

              int[] arr = {11,22,33,44,55,66,77,99,0,-1};

              printArray(arr);



              int[] arr2 = new int[]{1,2,3,4,5,6};



              printArray( arr2  );

       }

       //把打印数组的独立代码单独抽取到一个方法中

       /*

              在定义函数的时候,时刻要清楚当前的函数有没有返回值,还要确定当前的方法要不要接受参数

       */

       public static void printArray( int[] arr )

       {

              //打印出 数组之间用 逗号隔开

              for( int i=0 ; i<arr.length ; i++ )

              {

                     //这里需要对输出的数据进行判断,是否是最后一个数据

                     if( i != arr.length - 1  )

                     {

                            System.out.print(arr[i] + ",");

                     }

                     else

                     {

                            System.out.println(arr[i]);

                     }

              }

       }

}

 

6.3、案例:数组求和

 

class ArrayTest3

{

       public static void main(String[] args)

       {

              //演示数组的求和

              double[] arr = {1.1,3.8,4.2,1.9};



              double sum = getArraySum(arr);



              System.out.println("sum="+sum);

       }

       //定义功能计算数组中所有数据(元素)和值

       /*

         1、有没有返回值?

               有,数组中所有数据的和值,返回值类型和 和值一致



          2、要不要接受参数?

               要,具体的数组

       */        
     public static double getArraySum( double[] arr ){

              //定义一个变量,保存和值

              double sum = 0.0;


              //遍历取出数组中每个空间中的数据

        for ( int i=0; i<arr.length ; i++ ){

                sum = sum + arr[i];

        }

              return sum;

       }  

  }

            

 

6.4、案例:数组求最值

 

//数组的最值问题:

/*

       在对数组求最值的时候,一般我们会假设一个值为最大值或者最小值,

       然后遍历数组中的所有空间,和假设的这个值进行大小比较,只要从

       数组中取出的值比假设的值大 或者 小, 就进行替换。

       最终把数组遍历完成,就能找到最大值 或者 最小值

 

       一般要求假设的这个值一定是数组中存在的值。

 

*/

class ArrayTest4

{

       public static void main(String[] args)

       {

              int[] arr = {11,22,33,44,55,66,77,99,0,-1};

              int max = getArrayMax(arr);

              System.out.println("max = " + max);

       }

       /*

              定义函数;计算数组中的最大值

              1、有返回值,计算出来的最大值

              2、需要接收参数,那个数组

       */

       public static int getArrayMax( int[] arr )

       {

              //假设一个最大值

              int max = arr[0] ;



              for ( int i = 1 ; i<arr.length ; i++ )

              {

                     //判断从数组中取出的值 和 假设的值大小关系

                     if( max < arr[i] )

                     {

                            max = arr[i];

                     }

              }

              return max;

       }

}

6.5、将数组转成字符串

分析:把数组变成字符串,可以使用字符串与+号的连接。

int[] arr = {11,22,33,44,55,66,77,99,0,-1};

得到一个字符串 “11,22,33,44,55,66,77,99,0,-1”

需要对数组进行遍历,在遍历之前定义一个String str = “”;在遍历的过程中,每取出数组中的一个数据,然后就可以str进行连接,变成一个更长的字符串。

例如:当取出 arr[0]   str = str + arr[i] + “,”;

 

 

6.6、数组反转

反转:int[] arr = {11,33,55,66,88,0,-1};

反转之后要求arr指向的数组中的数据是:

{-1,0,88,66,55,33,11}

 

思路:上述需求就是交换数组中某2个空间中的值,交换的条件是第一个空间和最后一个空间互换,第二个和倒数第二个互换,以此类推。

提示:可以在循环中定义2个变量,一个从0下标开始往后走,另外一个从length-1位置往前走,每循环一次,就可以取出数组中的某2个空间,然后使用第三方变量进行交互。直到中间不再交互,停止的条件是从前往后的下标大于等于从后往前的下标时,表示整个数组交互结束。

 

 

6.7、数组的使用思想

数组:称为一类容器。它中可以保存多个数据。

当我们有多个数据的时候,并且数据的类型是统一的,同时个数也是确定的,这时就可以使用数组保存。

 

数据少了使用变量保存,数据一旦多了,就使用数组保存。

 

七、二维数组

7.1、二维数组定义

int[] arr = new int[100]; 在堆中开辟连续的100个空间。相当于开辟一行空间,这一行空间中拥有100列。

二维数组:

定义数组,但是这个数组拥有多行,而每行有拥有多列。

 

数据类型[][]  数组名 = new 数据类型[行的个数][每行中列的个数];

 

int[][] arr = new int[3][3]; 在堆内存中开辟一个二维数组,当前共计有三行,每行有三列。

 

7.2、二维数组内存图解

int[][] arr = new int[3][3];

 

二维数组在使用的时候,需要先通过二维数组的名+下标,找到管理每个一维数组的空间,然后再通过这个一维数组中的地址真正的去找到可以保存数据的那个真是空间。

 

7.3、二维数组的其他定义格式

一、数据类型[][] 数组名 = {

{值,值,值........},

{值,值,值........},

.......

};

 

二、数据类型[][] 数组名 = new 数据类型[行长度][];

数组名[下标] = new 数据类型[每个一维数组的长度];

 

int[][] arr = new int[4][];

arr[0] = new int[6];

arr[1] = new int[8];

arr[2] = new int[10];

arr[3] = new int[9];

 

7.4、二维数组遍历

二维数组的遍历:必须使用循环嵌套。

外循环提供二维数组的行下标,内循环提供每行中的列下标。

class ArrayDemo2

{

       public static void main(String[] args)

       {

              //二维数组的遍历



              int[][] arr = new int[3][];



              for ( int i=0; i<arr.length ;i++ )

              {

                     System.out.println("arr["+i+"] = "+arr[i]);

              }



              System.out.println("============================");



              int arr2[][] = {

                                 {11,22,33},

                                 {44,555,666,777,888},

                                 {9,7,5,4,1,11,-1}

                              };

              //遍历二维数组

              for ( int i=0 ; i<arr2.length ;i++ )  //提供行的下标

              {

                     for ( int j=0; j<arr2[i].length ;j++ )  //提供每行中的列下标

                     {

                            System.out.print(arr2[i][j] +" ");

                     }

                     System.out.println();

              }

       }

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值