java 11:数组作为函数参数,数组做为函数返回值

1 数组作为参数

我们可以将数组作为参数,传入到函数中,其实就像我们main函数中 public void main(String [] args){};就是用数组作为函数参数;

又如,

  1. public class ArrayPar  
  2. {  
  3.     public static void printArray(int [] array)  
  4.     {  
  5.         for(int i=0;i<array.length;i++) 
  6.             System.out.print(array[i]+"  ");  
  7.     }  
  8. }  
我们可以这样调用 ArrayPar.printt(new int[ ]{3,2, 5,67});调用数组

这里的new int[ ]{3,2,5,67};他也是一种创建数组的方法,只是这种方法创建出来的数组是没有名字的,所以叫匿名数组。很多时候在只使用一次的时候可以使用匿名数组的方法法,类似的还有匿名类。

Java uses pass-by-value to pass arguments to a method. There are important differences
between passing the values of variables of primitive data types and passing arrays.
■ For an argument of a primitive type, the argument’s value is passed.
■ For an argument of an array type, the value of the argument is a reference to an array;
this reference value is passed to the method. Semantically, it can be best described as
pass-by-sharing, i.e., the array in the method is the same as the array being passed.
So if you change the array in the method, you will see the change outside the
method.

java 使用值传参(pass_by_value)的方式来传递函数参数,只是值传递方式在处理原始数据类型参数与引用类型参数时候有不同,如果一个参数是原始数据类型,那么参数变量的值传递进去。如果是引用类型,是传进了引用变量的值(也就是说,只是将指向数据的引用的值给传进去了,也就是被调用的函数新建的空间放的是这个引用的值,那么也就是也指向了数组存在的内存),所以同样是值传递,引用类型的传入的当然是引用变量的值,指向了同一数组,那么函数内对数组进行的修改在函数退出后依旧是有效的。

例子:

  1. public class ArrayPar  
  2. {  
  3.     public static void main(String [] args)  
  4.     {  
  5.         int x=1;  
  6.         int y[]={1,2,3};  
  7.         change(x,y);  
  8.         System.out.println("x="+x+",y[0]="+y[0]);  
  9.     }  
  10.     public static void change(int num,int [] array)  
  11.     {  
  12.         num=100;  
  13.         array[0]=100;  
  14.     }  
  15. }  

图形表示:


这里同时注意一下,当我们用new 以及malloc这些的内存空间是在堆上heap,而像我们被调用的函数中使用的这些变量等在栈上。在调用changes时候,x的值被传入,在被调用的函数中重新开辟一个空间来放这个基本数据类型参数,但是int [ ] y ,将y传入其实就是传入了引用,在被调用的函数的栈上只会开辟一个空间来存放这个引用,所以被调用的函数与调用者 中两个引用指向堆上同一块内存。


2 数组做为函数返回值

  1. public static<span style="color:#ff0000;"int []</span> reverse(int [] array)  
  2. {  
  3.     int [] result=new int[array.length]  
  4.     for(int i=0;i<array.length;i++)  
  5.     {  
  6.         result[i]=array[lenght-i];  
  7.     }  
  8.     return result;
  9. }  
在将数组作为函数返回值时候如上红色标出的,就是在函数名字前加上返回值类型是int [ ] 表示返回一个int型数组,在函数体内最后返回是result这样的函数引用。


Case Study: Counting the Occurrences of Each Letter

write a program to count the occurrences of each letter in an random array of  lower  characters.

那么我们可以怎么做呢?

1)首先是要产生一个随机char数组  creatArray();(是否记得前边说过产生[a,a+b)之间的一个随机数 为  a+Math.random()*b,是否记得我们创建过获取任意字符的一个类?)

2) 创建一个数组 int [ ] count,长度26,准备来存放各个字母的计数

3)对数组进行循环 , 每读取一个字母ch,则 count[ch-'a']++;

  1. class RandomChar  
  2. {  
  3.     public static char getRandomChar(char ch1,char ch2)  
  4.     {  
  5.         return (char)(ch1+Math.random()*(ch2-ch1+1));  
  6.     }  
  7.     public static char getLowerCaseLetter()  
  8.     {  
  9.         return getRandomChar('a','z');  
  10.     }  
  11.     public static char getUpperCaseLetter()  
  12.     {  
  13.         return getRandomChar('A','Z');  
  14.     }  
  15.     public static char getDigitalLetter()  
  16.     {  
  17.         return getRandomChar('0','9');  
  18.     }  
  19.     public static char getRandomLetter()  
  20.     {  
  21.         return getRandomChar('\u0000','\uFFFF');  
  22.     }  
  23. }  
  24. public class CountOccur  
  25. {  
  26.     public static void main(String [] args)  
  27.     {  
  28.          char [] array=CreateArray();  
  29.          int [] count = new int[26];  
  30.          for(int i=0;i<array.length;i++)  
  31.          {  
  32.              count[array[i]-'a']++;  
  33.          }  
  34.          for(int i=0;i<count.length;i++)  
  35.          {  
  36.             System.out.print((char)(i+'a')+": "+count[i]+"    ");  
  37.             if((i+1)%10==0) System.out.println();  
  38.          }  
  39.            
  40.            
  41.     }  
  42.     //产生一个100个元素的小写随机数组  
  43.     public static char[] CreateArray()  
  44.     {  
  45.         char [] a=new char[100];  
  46.         for(int i=0;i<a.length;i++)  
  47.         {  
  48.             a[i]=RandomChar.getLowerCaseLetter();  
  49.         }  
  50.         return a;  
  51.     }  
  52. }  



3 可变长度参数列表

You can pass a variable number of arguments of the same type to a method. The parameter in
the method is declared as follows:
typeName... parameterName
In the method declaration, you specify the type followed by an ellipsis Only one vari-
able-length parameter may be specified in a method, and this parameter must be the last para-
meter. Any regular parameters must precede it.
Java treats a variable-length parameter as an array. You can pass an array or a variable
number of arguments to a variable-length parameter. When invoking a method with a variable
number of arguments,
Java creates an array and passes the arguments to it

我们可以传递类型相同,但个数可以变化的参数到函数中,如果有这个需求的话,这时候我们只需要在形式参数中使用 typename...parameterName就可以达到这个目的,要注意,在这里声明的该变长参数必须是最后一个参数,任何常规参数必须在他之前,也就是说你可以有 MethodName(char b, double c, int ... nums) 这样的形式即int ... nums必须在最后一个位置,你不能将int ... nums 声明在参数参数列表的非最后位置。

java将可变长参数当做数组对待。可以将一个数组或者可的参数个数传递给该参数(注意,我们这里说该参数就是 typeName ... parameterName这整个结构),无论哪种形式,java会创建一个数组并把参数传给他,注意这里体会原文说的When invoking a method with a variable
number of arguments, java Create an array and passes the arguments to it
,也就是说,如果你是传入几个变长的变量,那么在调用时候java先将创建一个数组来装这几个实际参数,然后再执行调用的函数,如果本身我们传入一个数组,其实他并不会创建一个新的数组来装,还是一样像上面指向了已经分配的数组空间,所以在被调用的函数中对数组的改变在退出时候还是有效的(这是我用例子试了下体会到的)

  1. public class VariablePar  
  2. {  
  3.     public static void main(String [] args)  
  4.     {  
  5.         int array[]={1,4,7,2,0};  
  6.         System.out.println("max="+findMax(array));  
  7.         ifChange(array);  
  8.         System.out.println("array[0]="+array[0]);  
  9.         ifChange(1,45,33);  
  10.     }  
  11.     public static int findMax(int ... nums)  
  12.     {  
  13.         if(nums.length==0)   
  14.         {  
  15.             System.out.println("No argumment passed");  
  16.             return -1;  
  17.         }  
  18.         int max=nums[0];  
  19.         for(int i=1;i<nums.length;i++)  
  20.         {  
  21.             if(max<nums[i]) max=nums[i];  
  22.         }  
  23.         return max;  
  24.     }  
  25.     //测试这里究竟是新创建一个数组还是相当于把引用传进来而已  
  26.     public static void ifChange(int ... nums)  
  27.     {  
  28.         nums[0]=100;  
  29.     }  
  30. }  
这里,我们从findMax中看到,他不用先说明 什么就可以直接使用nums.lenght 说明确实java是完全将这类型的参数当做一个数组来处理了,二在ifChange中,我们看到输出的是array[0]=100,说明我们在调用ifChange(array)时候并不是重新创建一个新的数组,而是还是一样像前边的传入了引用,被调用者还是指向了相同的数组空间。但是在ifChage(1,45,33)这个调用时候,java就会先new int[ ]{1,45,33} 这样,然后形参nums再指向它,其实这样返回后应该就不会改变了1的值吧?
  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
函数的定义 什么是函数? •函数就是定义在类中的具有特定功能的一段独立小程序。 •函数也称为方法。 函数的格式: •修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,...) { 执行语句; return 返回值; } 返回值类型:函数运行后的结果的数据类型。 参数类型:是形式参数的数据类型。 形式参数:是一个变量,用于存储调用函数时传递给函数的实际参数。 实际参数:传递给形式参数的具体数值。 return:用于结束函数返回值:该函数运算后的结果,该结果会返回给调用者。 函数的特点 定义函数可以将功能代码进行封装 便于对该功能进行复用 函数只有被调用才会被执行 函数的出现提高了代码的复用性 对于函数没有具体返回值的情况,返回值类型用关键字void表示, 那么该函数中的return语句如果在最后一行可以省略不写。 注意: •函数中只能调用函数,不可以在函数内部定义函数。 •定义函数时,函数的结果应该返回给调用者,交由调用者处理。 函数的应用 两个明确 •明确要定义的功能最后的结果是什么? •明确在定义该功能的过程中,是否需要未知内容参与运算 示例: •需求:定义一个功能,可以实现两个整数的加法运算。 •分析: •该功能的运算结果是什么?两个数的和,也是一个整数(int) •在实现该功能的过程中是否有未知内容参与运算?加数和被加数是不确定的。(两个参数int,int) •代码: int getSum(int x,int y) { return x+y; } 函数的重载(overload) 重载的概念 在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。 重载的特点: 与返回值类型无关,只看参数列表。 重载的好处: 方便于阅读,优化了程序设计。 重载示例: //返回两个整数的和 int add(int x,int y){return x+y;} //返回三个整数的和 int add(int x,int y,int z){return x+y+z;} //返回两个小数的和 double add(double x,double y){return x+y;} 函数的功能一样,仅仅是参与运算的未知内容不同时, 可以定义多函数,却使用统一函数名称,这样方便阅读。 在调用时,虚拟机通过参数列表的不同来区分同名函数数组 数组的定义 概念 同一种类型数据的集合。其实数组就是一个容器。 数组的好处 可以自动给数组中的元素从0开始编号,方便操作这些元素。 格式1: 元素类型[]  数组名 = new 元素类型[元素个数或数组长度]; 示例:int[] arr = new int[5]; 格式2: 元素类型[] 数组名 = new 元素类型[]{元素,元素,……}; int[] arr = new int[]{3,5,1,7}; int[] arr = {3,5,1,7}; 数组内存结构 内存结构 Java程序在运行时,需要在内存中的分配空间。为了提高运算效率,有对空间进行了不同区域的划分,因 为每一片区域都有特定的处理数据方式和内存管理方式。 栈内存   用于存储局部变量,当数据使用完,所占空间会自动释放。 堆内存   数组和对象,通过new建立的实例都存放在堆内存中。   每一个实体都有内存地址值   实体中的变量都有默认初始化值   实体不在被使用,会在不确定的时间内被垃圾回收器回收 方法区,本地方法区,寄存器 数组操作常见问题   数组脚标越界异常(ArrayIndexOutOfBoundsException) int[] arr = new int[2]; System.out.println(arr[3]); 访问到了数组中的不存在的脚标时发生。   空指针异常(NullPointerException) int[] arr = null; System.out.println(arr[0]); arr引用没有指向实体,却在操作实体中的元素时。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值