黑马程序员——003——函数、数组

来源:互联网 发布:二战德国实力 知乎 编辑:程序博客网 时间:2024/06/06 19:10
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

我们用一个小程序来开篇热身,也算是对上一小节的复习:
程序1:使用for循环打印九九乘法表。
——————————————————————————

class Demo3_1{        /*        程序1:使用for循环打印九九乘法表。        思路:采用嵌套循环的方式。        */        public static void main(String[] args)        {                for(int i=1;i<=9;i++)                {                        for(int j=1;j<=i;j++)//关键是这里的j<=i,是最巧妙的地方                        {                                //是用制表符\t,能够让排列更加对齐                                System.out.print(j+"*"+i+"="+(i*j)+"\t");                        }                        //当输出语句什么内容都不写的时候,就相当于一个换行符                        System.out.println();                }        }}

——————————————————————————
执行结果如下图:
这里写图片描述
——————————————————————————
如果我们有个需求就是只需要1到6的乘法表的话,程序该如何修改?如下:
——————————————————————————

class Demo3_2{        /*        程序2:只需要1到6的乘法表        思路:采用嵌套循环的方式+break语句。        */        public static void main(String[] args)        {                for(int i=1;i<=9;i++)                {                        for(int j=1;j<=i;j++)//关键是这里的j<=i,是最巧妙的地方                        {                                //是用制表符\t,能够让排列更加对齐                                System.out.print(j+"*"+i+"="+(i*j)+"\t");                        }                        //当输出语句什么内容都不写的时候,就相当于一个换行符                        System.out.println();                        if(i==6)                                break; //当循环执行完第六行,就是用break跳出for循环                }        }}

——————————————————————————
执行结果如下图:
这里写图片描述
——————————————————————————
今天我们首先讲的是函数,我们前面也已经提到过,函数也可以做叫方法,因为它适用于解决问题的。
那么官方的定义就是:定义在类中的具有特定功能的一段独立小程序。也称方法。
——————————————————————————
格式:
修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,…)
{
执行语句;
return返回值;
}
——————————————————————————
其中:
—返回值类型:函数运行后的结果的数据类型。
—参数类型:是形式参数的数据类型。
—形式参数:是一个变量,用于存储调用函数时传递给函数的实际参数。
—实际参数:传递给形式参数的具体数值。
—return:用于结束函数。
—返回值:该值会返回给调用者。
——————————————————————————
特点:
—定义函数可以将功能代码进行封装,便于对该功能进行复用。
—函数只有被调用才会被执行。
—函数的出现提高了代码的复用性。
—对于函数没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。
——————————————————————————
注意:
—①函数中只能调用函数,不可以在函数内部定义函数。
—②定义函数时,函数的结果应该返回给调用者,交由调用者处理。
——————————————————————————
如何定义一个函数?
—明确要定义的功能最后的结果是什么。
—明确在定义该功能的过程中,是否需要未知内容参与运算。
——————————————————————————
函数的一个重要特性——重载(override)
—概念:在同一个类中,允许存在一个以上的同名函数,只要它们的参数列表的个数或者参数类型不同即可。
—特点:与返回值类型无关,只看参数列表。
—好处:方便于阅读,优化了程序设计。
——————————————————————————
—示例:
//返回两个整数的和
int add(int x,int y){return x+y;}
//返回三个整数的和
int add(int x,int y,int z){returnx+y+z;}
//返回两个小数的和
double add(double x,double y){return x+y;}
——————————————————————————
什么时候用到重载?
当定义的功能相同,但参与运算的未知内容不同。那么,这时就定义一个函数名称以表示起功能,方便阅读,而通过参数列表的不同来区分多个同名函数。
——————————————————————————
那么现在再来看一个示例程序:
输出如下矩形(5*7):


  • *
  • *
  • *

——————————————————————————

/*输出如下矩形(5*7):********       **       **       *********/class Demo3_3{        public static void main(String[] args)        {                for(int j=0;j<5;j++)                {                        if(j==0 || j==4)//如果是首末行则输出七个*                                for(int i=0;i<7;i++)                                        System.out.print("* ");                        else////如果不是首末行则输出头尾*                        {                                //打印出只有两的头的*                                System.out.print("* ");                                for(int k=0;k<5;k++)                                        System.out.print("  ");                                System.out.print("* ");                        }                        //一行输出完换行                        System.out.println();                }        }}

——————————————————————————
执行结果如下图:
这里写图片描述
——————————————————————————
现在需求有所改变,又想要输出10*11的矩形,那么我们每次都需要回去修改源代码,非常的繁琐,因此这里就可以运用函数了。
我们把长宽变成两个参数,让调用函数的人使用参数传进去,如下则程序:
——————————————————————————

/*将输出矩形封装成方法,使用方法得到10*11矩形*/class Demo3_4{        public static void main(String[] args)        {                getRec(5,7);//输出5*7矩形                getRec(10,11);//输出10*11矩形        }        static void getRec(int height,int width)        {                for(int j=0;j<height;j++)                {                        if(j==0 || j==height-1)//如果是首末行则输出七个*                                for(int i=0;i<width;i++)                                        System.out.print("* ");                        else////如果不是首末行则输出头尾*                        {                                //打印出只有两的头的*                                System.out.print("* ");                                for(int k=0;k<width-2;k++)                                        System.out.print("  ");                                System.out.print("* ");                        }                        //一行输出完换行                        System.out.println();                }        }}

——————————————————————————
这就是函数在实际开发中的应用,我们把一个复杂的功能封装起来,根据变量参数之间的关系规律来编程,来简化代码,才是最好的。
有这么一句话:一个优秀的程序员是不会写出毁灭地球的方法的,他会写出毁灭行星的方法然后把地球当做参数传进去
Java中最小的功能单元就是函数。
另外,这里再对上文中的提到的方法的重载作补充,请看下面的这则程序:
——————————————————————————

class Demo3_5{        public static void main(String[] args)        {                System.out.println(add(1,2));//打印3                System.out.println(add(1,2,3));//打印6        }        /*求两个数的和*/        static int add(int a,int b)        {                return a+b;        }        //重载add方法        /*求3个数的和*/        static int add(int a,int b,int c)        {                return a+b+c;        }}

——————————————————————————
重载方法使用场景:
—当定义的功能相同,但是参数与运算的未知内容不同的时候,那么这时候就定义一个函数名称以表示其功能,方便阅读,而通过参数列表的不同区分多个同名字函数。
JVM会根据你传入的参数的不同进行不同方法的调用。
注意:只要方法同名并且参数类型不同,那就是重载。不用管返回类型是什么。
——————————————————————————
——————————————————————————
数组
概念:
—同一种类型数据的集合。简单的来说就是一容器,用来装东西的。
—数组的好处:使用数组的好处:可以自动给数组中的元素从0开始编号,方便操作这些元素。
数组格式:
—格式1:元素类型 [ ]数组名 = new 元素类型 [元素个数或数组长度] ;
——如: int [] arr = new int [3]; 也可以写成: int arr[] = new int[3];
—格式2:元素类型 []数组名 = new 元素类型 [ ]{元素1,元素2,…};
——如: int [] arr = new int []{1,2,3,4,5};
——还有一种简写的静态初始化格式:如: int [] arr={1,2,3,4,5};
——其中:new是用来在堆内存中产生一个容器实体。
—示例:int[] x = new int[3];
—示例:int[] x = {1,2,3,4,5};
————x[2] = 7;//将角标对应的数值,原来的2改成7
——这里的x并不是int类型,而是数组类型,是引用类型的一种。
数组在内存中的表现形式:
—Java程序在运行时,需要在内存中的分配空间。为了提高运算效率,有对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
—栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放。
—堆内存:
——①数组和对象,通过new建立的实例都存放在堆内存中。
——②每一个实体都有内存地址值。
——③实体中的变量都有默认初始化值。
——④实体不在被使用,会在不确定的时间内被垃圾回收器回收。
之所以要把空间细划分,因为每一片空间处理的方式不一样;
——————————————————————————
示例:
int[] x = new int[3];
//使用x的代码略
x=null;
/*当使用完x的时候,执行x = null;让x不在指向堆内存地址,堆内存中的就是垃圾,空间会被java垃圾回收机制不定时间回收;
*/
——————————————————————————
小插曲:
—Java和C++的关系:
——Java语言成长至C++,其优化了C++的一些特性,而变得更简单,尤其在内存这一块要比C++做的好,C++需要手动清楚不用的空间,如果程序员忘记做了,那么内存会越来越少,计算机就越来越慢,最后死机;
注意1:
—堆内存的有没有垃圾存在,需要看有没有变量指向它,有则不是垃圾,否则没有就死垃圾,会被垃圾回收器回收再利用。
注意2:
—int[] x = new int[3];
—int[] y = new int[3];
——x和y指向的是堆内存中两块不同的区域,两者数据的使用是互不干扰的。
——————————————————————————
关于数组有连个常见的问题需要注意一下:
—1.数组越界问题
—例:
——int[] arr = new int[2];
——System.out.println(arr[3]);
——原因:访问到了数组中的不存在的脚标时发生。
—2.空指针问题
—例:
——int[][] arr= new int[3][2];
——//使用完arr后
——int[]arr = null;
——System.out.println(arr[0]);
——原因:arr引用没有指向实体,却在操作实体中的元素时。
—Java中会把出现的问题用特有的机制表示,Java中叫做异常,我们会在后面涉及到。
——上面的1中问题,Java中使用ArrayIndexOutOfBoundsException表示。
——上面的2中问题,Java中使用NullPointerException表示。
——从单词的直译上,我们也能窥探一二,能够知道异常的原因。
————————————————————————————
多维数组(数组中的数组 )
—以二维数组为例:
—格式1: int[][] arr= new int[3][2];
—解释:以上格式表示定义了名称为arr的二维数组。有3个一维数组,每一个一维数组中有2个元素。一维数组的名称分别为arr[0],arr[1],arr[2]。给第一个一维数组1脚标位赋值为78写法是:arr[0][1] = 78。
一格式2: int[][] arr= new int[3][];
一注意:此种格式中每个一维数组都是默认初始化值null。
一格式3:int[][] arr = {{3,8,2},{2,7},{9,0,1,6}};//每一个一维数组中具体元素都初始化了。
一注意:一种特殊定义写法:int[]x,y[]; x是一维数组,y是二维数组。
二维数组在内存中的分配情况示例:
—(左边是栈内存,右边是堆内存);
这里写图片描述
注意:
—二维数组的声明还可以这样:int[] y[];
——但是不推荐这样写,因为这样导致阅读性变差了,几乎没有人这么写,如果在开发中这样写,项目组长肯定和你玩命!
————————————————————————————
当我们掌握了,数组这个容器候的时候,我们可以思考其应用了:
—1.是一个容器,用来存放数据;
—2.对其中的数据进行大小排序;
—3.对其中的数据进行某一个值的查找;
那现在我们就用三则小程序来结束这小节。
程序1:
—使用数组完善前一小节中的获取一个数的十六进制程序;
————————————————————————————

/*程序1:—使用数组完善前一小节中的获取一个数的十六进制程序;*/class Demo3_6{        static char c;        public static void main(String[] args)        {                toHex(60); //打印3C,60的十六进制是3C                toHex(90); //打印5A,90的十六进制是5A        }        static void toHex(int a)        {                //定义一份表格(数组),让十六进制的每个数字                //都有一个字母对应                char[] cs = new char[]{'1','2','3','4','5','6','7','8','9',                                                        'A','B','C','D','E','F'};                //定义一个临时容                char[] cs_result = new char[10];                //让角标等于临时容器的最后一个角标                int indexOfCs_result = cs_result.length-1;                int temp = a;                while(true)                {                        if(temp<=0)                                break;                        //低四位                        int num = temp&15;                        temp = temp>>>4;                        //从最后一个开始往前存                        cs_result[indexOfCs_result--] = cs[num-1];                }                for(int i=0;i<cs_result.length;i++)                {                        if(cs_result[i]==0)//因为在堆内存中的char类型,默认值为0                                continue;                        else                                System.out.print(cs_result[i]);                }        }}

————————————————————————————
执行结果:
这里写图片描述
————————————————————————————
程序2:
—对数组中的数据进行排序,使用冒泡排序算法;
————————————————————————————

/*程序2:—对数组中的数据进行排序,使用冒泡排序算法;*/import java.util.*;class Demo3_7{        public static void main(String[] args)        {                int[] a = new int[]{5,6,13,1,3,2,9,11};                //排序前结果                System.out.println("初始数组\t"+Arrays.toString(a));                popUpSort(a);//调用冒泡排序方法                //排序后结果                System.out.println("排序结果\t"+Arrays.toString(a));                /*                这个方法能够将数组转换成字符串打印出来                Arrays.toString(数组)                */        }        /*冒泡排序*/        static void popUpSort(int[] a)        {                if(a==null)//防止a是null,导致空指针异常                        return;                //计数器                int count = 0;                for(int i=a.length-1;i>0;i--)                {                        for( int j=0;j<i;j++)                        {                                if(a[j]>a[j+1])//如果                                        swap(a,j,j+1);                        }                        count++;                        System.out.println("第"+count+"轮\t"+Arrays.toString(a));                }        }        /*数组a中角标为index1和index2的数值交换*/        static void swap(int[] a,int index1,int index2)        {                int tmp = a[index1];                a[index1] = a[index2];                a[index2] = tmp;        }}

————————————————————————————
执行结果:
这里写图片描述
————————————————————————————
程序3:
—对数组中的数据进行排序,使用冒泡排序算法,并使用折半查找算法查找其中的某个数值;
————————————————————————————

/*程序3:—对数组中的数据进行排序,使用冒泡排序算法,并查找其中的某个数值;*/import java.util.*;class Demo3_8{        public static void main(String[] args)        {                int[] a = new int[]{5,6,13,1,3,2,9,11};                System.out.println("初始数组\t"+Arrays.toString(a));                popUpSort(a);                System.out.println("排序数组\t"+Arrays.toString(a));                System.out.println("查找数字9角标\t"+halfSearch(a,9));                System.out.println("查找数字5角标\t"+halfSearch(a,5));        }        /*折半查找*/        static int halfSearch(int[] a,int findMe)        {                int left = 0;                int right = a.length-1;                int mid=(left +right)/2; //首先获得中间的值                while(true)                {                        if(a[mid]>findMe)                        { //中间值大于目标,说明目标在左边                                right = mid-1; //因此中间角标的左边一个变成下一轮的右边界角标                        }                        else if(a[mid]<findMe)                        { //中间值小于目标,说明目标在右边                                left = mid+1; //因此中间角标的右边一个变成下一轮的左边界角标                        }                        else //否则就找到了,直接返回该角标值                                return mid;                        //每一轮都需要把角标定位在left和right的中间                        mid=(left+right)/2;                }        }        /*冒泡排序*/        static void popUpSort(int[] a)        { /*见程序2*/}         /*数组a中角标为index1和index2的数值交换*/        static void swap(int[] a,int index1,int index2)        { /*见程序2*/} }

————————————————————————————
执行结果:
这里写图片描述

0 0
原创粉丝点击