黑马程序员_循环语句、函数和数组
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
循环语句部分
一,循环语句 while ,do while ,for
1、while语句的格式 while(条件表达式){ 执行语句; }
2、do while 语句的格式 do{ 执行语句 ;}while(条件表达式);
相比较if语句来说,while和do while 语句是一个循环语句,在运行时候,如果条件表达式满足条件,她就会一直执行执行语句的部分;而if语句,当满足条件表达式的时候,只会执行一次。
注意:在dos见面运行无限循环时候,用ctrl+c 进行强制程序停止。
while 和do while 语句的相同处和不同处,看下列语句
//while 方式的循环语句
int x =1;
while (x<0)
{
System.out.println("Hello World!");
x++;
}
//do while 方式的循环语句
int y = 1;
do
{
System.out.println("do:x="+y);
y++;
}
while(y<0) ;
相同处:while 和do while语句其实都是循环语句,只要满足条件表达式就会执行里面的执行语句。
不同处:while是先判断条件表达式是否成立,成立即执行循环程序,不成立就会立即跳出。
do while是先执行一遍循环程序里的执行语句,然后在判断条件表达式是否成立,成立就会继续执 行,不成立就会跳出。
所以上述语句中,do while 会执行一次 y ,while 一次都不会执行
注意while()后面紧跟一个分号 即 :while(条件表达式); 此时语句是成立的,只是会变成无限循环。
3、for 循环语句 格式为:for(初始化表达式;循环条件表达式;循环后操作表达式){ 执行语句 ;}
初始化表达式是第一步,只会执行一次,其后就会执行后面的语句,而且里面的变量在for循环结束的时候里面的变量就消失了。具体程序如下:
class ForDemo
{
public static void main(String[] args)
{
for(int x=0;x<3;x++)
{
System.out.println("x="+x);
}
System.out.println("x===="+x); 此时,结果为空,就是说没有变量x
int y = 0;
while (y<3)
{
System.out.println("y="+y);
}
System.out.println("y===="+y); 此时,结果又y
}
}
相对于while语句,它的初始化语句在while循环语句外面,当while语句循环结束的时候,变量还在。
这样就会出现一个编写程序选择:1)如果增量变量只用于循环语句,定义在for语句中,只在for语句中有效,佛for语句完成后就会释放内存用for循环语句。
2) 如果增变变量循环语句后可用,定义在while语句之外,就可用while语句
3)for和while语句可以进行互换,如果需要定义循环变量,for更为合适
for循环里面条件表达式,注意是条件表达式,必须有真假。其他两个表达式可以是其他类型的表达式,当其中含有多个表达式的时候,用逗号隔开即可。例如:for(int x=1,y=9;x<3,y<12;x++,y++)。
for语句中的初始化表达式和循环后表达式也可以不写。
小细节:无线循环最简单表达式。
(1) for(;;){ } 条件表达式为空,即系统会默认为true
(2) while(true){ }
循环语句一定要注意,哪些语句要参与循环,哪些不需要参与循环,确定需要几个未知参数,确定类型以及各自循环的姿态。涉及的思想:累加思想和计数器。就是就是通过一个变量来记录住数据的变化。
循环嵌套语句的联系:class ForForDemo
{
public static void main(String[] args)
{
for(int x =0;x<3;x++)
{
for(int y=0;y<4;y++)
{
System.out.println("ok");
}
System.out.println();//只有一个功能就是换行
}
}
}
打出的结果是一个有 * 好组成的长方形,内外循环相对于此处来说,就是外循环控制行数,内循环控制列数。当列数改变时,可以改变for循环内循环语句里的初始化值或者条件表达式,使之随着外循环的变化而变化,做出相应的改变。
小技巧:在用循环语句尤其是嵌套循环语句来制作像表格一类的东西的时候,为了对齐 ,可以再输出语句里加入 " \t " 即制表符来进行制表。
二,break和continue
不同点:
1)应用范围的不同:
break语句应用范围: 选择语句(switch语句)和循环语句
continue语句以应用范围: 循环语句
2)作用不同:
break是跳出当前循环语句,注意此处跳的是它所在的循环,比如内循环
continue是结束本次循环开始下次循环
相同点:这两个语句离开应用范围都是没有意义的,在作用范围外会编译出错
这两个语句单独存在下面都不是不可以有语句的因为执行不到,所以两个语句后面不跟任何语句。
所以我们当写到无线循环的程序时,可以通过break语句来判断用户或者其他的数据满足条件语句,来跳出无限循环语句。
小细节:可以在循环语句前加上 名称 :循环语句 就是对循环语句做标号,相当于起名字。如w:for(;;),此处w就是循环语句做的标号。通过此小标号,可以这样运用,如:在内循环中加入break w ;就可以把外循环关闭。
函数
一、函数
函数就是定义在类中的具有特定功能的一段独立的小程序。
实际上就是一个可以实现固定功能的方法,只是把这种发法装到一个可以用于调用的程序里,这样我们以后需要这个特定功能,只要调用这个函数就可以实现。函数就是方法,方法就是函数。
对于函数调用,就是提高了程序的复用性,也方便日后的程序的使用。
函数其实就是讲一段特定功能的代码进行封装,只有被调用的时候才会被执行。
函数之间可以相互调用。
函数的格式: 修饰符 返回值类型 函数名 (参数类型 形式参数1,参数类型 形式参数2,.....)
{
执行语句;
return 返回值;
}
在主函数中调用格式为 函数名(参数)
注意,1)如果函数中没有具体的返回值情况,返回值类型用关键字void表示,那没该函数中的return如果再最后一行可以省略不写。像是现在基础用到的打印。
2)函数中只能调用函数,不可以在函数内部定义函数。
在主函数中调用格式为 函数名(参数)
3)返回值类型为void时,不能用打印语句输出
二、重要思想: 如何定义一个函数呢
1、既然函数是一个独立的功能,那么该功能的运算结果是什么先明确
就是说有一个需求,一般是这个需求要一个结果或者其他什么东西,那么我这个功能就得达到这个结果或者目标,那么我就知道该功能运算结果是什么,所以要先明确。运算结果明确就是在明确返回值类型。
2、在明确都在定义该功能的过程中是否需要未知的内容参与运算
这个功能达成一个结果,里面有未知的或者是外面输入的,即是未知的参数,这个参数需要参与运算,那么就定义它。未知参数明确,就是在明确参数列表和参数个数。
函数调用举例:
class FunctionTest
{
public static void main(String[] args)
{
juXing(5,6);
kouJue();
System.out.println("Hello World!");
}
//打印矩形的一个调用函数
public static void juXing(int a,int b)
{
for(int x=0;x<a;x++)
{
for (int y=0;y<b ;y++ )
{
System.out.print("*");
}
System.out.println();
}
}
//定义一个功能,打印九九乘法口诀表
public static void kouJue()
{
for (int x=1;x<=9 ;x++ )
{
for (int y=1;y<=x ;y++ )
{
System.out.print(x+"*"+y+"="+x*y+"\t");
}
System.out.println();
}
}
}
两个函数都是没有返回值类型,在矩形条用函数中,行列数是有用户输入的,所以定义在参数列表中。九九乘法表中,是要直接打印一个九九乘法表,所以并没有需要输入的未知参数,所以直接用for循环完成它。
注意,调用,直接调用函数,并不需要再写打印语句,这就是因为调用的函数里返回类型是void型的,所以,不能再主函数里再次写打印语句打印结果。
三、函数的重载
在同一个类中,允许存在一个以上的同名函数,只要他们的参数个数或者参数类型不同即可。
就是说重载只看参数列表,与其他的无关。注意,只和参数列表有关系。
如:
取和的运算 public static int add(int x ,int y)
public static int add(int x, int y, int z )
public static double add(double x,double)
以上三个函数重载了,1)和2)函数的名称一样,返回值类型一样,但是参数列表不一样,个数不一样
2)和3)函数名称一样,参数列表的参数类型不一样,即是重载
有上可知,当定义功能相同,但参与运算的未知内容不同,那么此时就定义一个函数名称以表示其功能,方便阅读,而通过参数列表的不同来区分多个函数。
数组部分
一、数组
同一种类型数据的集合,数组就是一个容器。
数组可以自动给数组中的元素开始编号,方便操作这些元素。
格式1:元素类型[ ] 数组名 = new 元素类型[元素个数或者数组长度];
格式2:元素类型[ ] 数组名 = new 元素类型[ ]{元素,元素,... };
new会在容器中产生一个可以存储数据的实体。数组类型数据引用数据类型。
表示数组中每个元素的具体位置格式为:数组名[位置数 ] 位置数是从零开始的
数组建立在内存中的流程:
int [ ] x = new int[ ];
int [ ] x 先会在栈内存中建立一个x,使用数组的时候,次值存在,数组使用完成后就是释放栈内存,就是说栈内存是一个临时性的内存空间。
小知识:所有局部变量,都定义在栈内存中
new 就是建立一个实体,实体包括数组和对象。只要运行new 就会在堆内存中分配空间。并且在其中每个元素都建立对应的角标,是从0开始的,一定要注意是从0开始的。
每个内存都有一个地址值,是二进制的,此时就把数组在内存中的地址值赋给x ,此时是一个赋值动作。
当数组建立的是,就会在内存中给默认初始化值,整型类0 ,布尔型为false。
null 空 ,只有引用类数据类型可以用这个关键字。如 x = null 就是把数组的地址值变为空,如果这样在程序里,就是得原数组没有地址值指向,所以,此时为垃圾,无效数据。
堆内存中的特点:1)地址值 2)默认初始化值 3)垃圾回收机制
其中垃圾回收机制,就是java里,本身会定期清理垃圾数据。
一个数组固定长度,比如3,当程序打印角标为3的时候,就会出错,但是程序编译的时候不会出错,语法上也没有错误。但程序一旦运行,就会显示角标出错。说明在编译程序的时候,数组并没有建立,程序开始运行的是数组才会建立起来。这个要注意。
二、数组的操作
一般的数组操作都会用到遍历。数组中有一个属性可以直接获取到数组元素的个数,length,使用方法为 数组名.length 。
1、常见操作以:遍历
一下为一个遍历数组的函数:
public static void printarr(int[] arr) 这是要获取一个元素为int型的数组
{
for (int x=0;x<arr.length ;x++ ) arr.length 为数组元素个数,牢记,数组部分常用
{
if(x!=arr.length-1)
System.out.print(arr[x]+",");
else
System.out.print(arr[x]);
}
}
2、常见操作二:获取数组元素最大值
思路:1)获取最值需要进行比较,每一次比较都会有一个比较大的值,因为该值不确定,通过一个变量进行临时存储。
2)让数组中每一元素都与这个变量中的值进行比较,如果大于变量中的值,就用该变量记录较大的值。
3)当所有元素比较完,那么该变量中的存储的就是数组中的最大值了
public static int arr(int[] arr) 返回值类型是int型
{
int max=arr[0];
for (int x=1;x<arr.length ;x++ ) 遍历数组
{
if (arr[x]>max) 相比较,记录最大值
{
max=arr[x];
}
}
return max; 返回最大值,这个一定要注意,出去void型不需要返回值,其他都需
} 要
这个只是int类型的数组,对其他类型的数组,获取最值的方法是一样的,只是数组元素数据类型不一样,所以可以建立重载函数。
3、选择排序
思路:
1、以角标为0的元素开始,与角标为1的数组进行比较,如果1的较小,则两者互换,再以角标为的0的元素与2角标的比较,如果小,则两者互换,依次类推。
2、进行比较,要遍历数组
public static void paiXuArr(int[] arr)
{
for (int x=0;x<arr.length-1 ;x++ ) 从0角标开始,到倒数第二个元素即可,最后一个自己不需要
{ 比较
for (int y =x+1;y<arr.length ;y++ ) 从x+1角标开始到最后一个角标元素,每个角标与x角标比较
{
if (arr[y]<arr[x])
{
int temp =arr[x]; 如果小,两者换位置(此处用第三方变量换位)
arr[x]=arr[y];
arr[y]=temp;
}
}
}
printarr(arr); 调用打印数组的函数
}
4、冒泡排序
思路:相邻两个元素进行比较 ,具体来说,就是角标0与角标1的相比,小的排在前、大的排在后,然后角标1的和角标2的比较,也是小的排在前,大的排在后,依次排序。到数组的最后一定是最大的在最后面。当第二次比较开始时,最后的元素不参与比较,照上比较后,第二大的元素就会排出来,以此类推。程序为
public static void maoPaoArr(int[] arr)
{
for (int x=0;x<arr.length-1 ;x++ ) ............................. 遍历数组元素,只需比较arr.length-1次
{
for (int y =0;y<arr.length-x-1 ;y++ ) ............................此处应注意y<arr.length-x-1 每次比较后比较的
{ 次数就会减少一次,就是减少x,所以-x是让每一次元素比较减
if (arr[y]<arr[y+1]) 少。如果元素个数为5,当y取到arr.length-1,即5-1=4时,y+
{ 1就是5,超出最大角标数4了,所以y最大只能取到3,所以
int temp =arr[y]; y<arr.length-x-1。
arr[y]=arr[y+1];
arr[y+1]=temp;
}
}
}
printarr(arr);
}
排序最快的为,希尔排序。
在以上程序中,要注意到共性的部分,比如位置置换,相对应的可以把这个功能单独写成一个函数,以待调用。
5、数组查找 折半查找
折半查找就是从中劈开,然后比较大小。所以,数组必须是有序的数组,注意是有序的数组。这种方法可以调高效率。具体程序例子:
public static int halfSearch(int[] arr,int key)
{
int min,max,mid;
min=0;
max=arr.length-1;
mid=(min+max)/2;
while(arr[mid]==key)
{
if (key>arr[mid])
min=mid+1;
else
max=mid-1;
if(min>max)
return -1;
mid=(min+max)/2;
}
return mid;
}
这个程序也可以用于把一个数插入到这个有序的数组,还保证数组有序,获取的位置就是返回最小角标min为数值。
6、二维数组
格式 int[ ][ ] arr = new int [3 ] [2 ]; 此处定义了一个名为arr的二维数组,二维数组中有有3个一维数组,每个一维数组里有两个元素。两个一维数组角标为0和1,每个一维数组里的元素角标按一维数组来排。所以,要是想赋值给第二个二维数组中最后一个元素,写成: arr[1][1] = 90
要是想初始化一个一维数组,写成 arr[1]=new int[1];
注意:在二维数组中
System.out.println(arr); 此时打印的是二维数组的地址值
System.out.println(arr[0]); 此时打印的是二维数组中第一个一维数组的地址值
int[ ][ ] arr = new int [3 ] [ ]; 此处第二个括号里不写值 此时在System.out.println(arr[0]); 结果是:null 。
因为每个数组是引用数据类型,所以默认初始化值为null。在这之后如果初始化一维数组,那么就在内存中开辟空间存放一维数组,并把这个一维数组的地址值付给相对应arr[0]、arr[1]、arr[2],实质指向一维数组七、进制转换的联系
class ArrayTest7
{
public static void main(String[] args)
{
toBin(-6);
System.out.println();
toBin(6);
System.out.println();
toHex(-60);
System.out.println();
toHex(60);
System.out.println();
}
public static void toBin(int num) ............//二进制转换
{
trans(num,1,1);
}
public static void toHex(int num)...............//十六进制转换
{
trans(num ,15,4);
}
public static void trans(int num,int base,int offset)..........................转换进制的基本调用函数
{
//建表
char[] chs = new char[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};..........制表
char[] arr= new char[32];..............................................建立一个容器
int pos = arr.length;.....................................................建立一个指针,为倒着记录进容器,先取最大值
while(num!=0)
{
int temp = num & base;
arr[--pos]=chs[temp]; 进行与运算和位移,把对应表里的字符记录到容器里
num = num>>>offset;
}
for(int x=pos;x<arr.length;x++)..........................................打印容器里的元素
{
System.out.print(arr[x]);
}
}
}