黑马程序员_循环语句、函数和数组

本文详细介绍了Java中的循环语句(while、do-while、for)的特点及使用场景,对比了它们之间的区别,并深入讲解了数组的概念、创建、初始化、遍历等基本操作,同时提供了数组排序、查找等高级应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

黑马程序员_循环语句、函数和数组

 

------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]);
  }
 }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值