【流程控制】【函数】【数组】【数组的操作】


引用一位师兄的思维导图,源地址,本篇内容7,9,10

程序流程控制 知识要点

判断结构 选择结构 循环结构

if和switch for和while的异同continue,break,return

无限循环最简单形式及其应用
编程思想:累加思想 计数器思想

函数和数组 知识要点

函数的定义 特点 应用 重载

数组常见操作 多维数组

 判断结构      三种格式

if            //if else        //if  elseif   else

 if语句特点:

       a,每一种格式都是单条语句。

b,第二种格式与三元运算符的区别:三元运算符运算完要有值出现。好处是:可以写在其他表达式中。

       c,条件表达式无论写成什么样子,只看最终的结构是否是true 或者 false;

//if else不一定有结果,三元运算符 :<表达式1><表达式2><表达式3>一定有一个结果

return a==b

选择结构

switch语句

格式:

switch(表达式)
{
       case取值1:
              执行语句;
              break;
       case取值2:
              执行语句;
              break;
       …...
       default:
              执行语句;
              break;
}

 switch语句特点:

    a,switch语句选择的类型只有四种:byte,short,int , char。

       b,case之间与default没有顺序。先执行第一个case,没有匹配的case执行default。

       c,结束switch语句的两种情况:遇到break,执行到switch语句结束。

d,如果匹配的case或者default没有对应的break,那么程序会继续向下执行,运行可以执行的语句,直到遇到break或者switch结尾结束。

循环结构

while语句格式:

while(条件表达式)
{
       执行语句;
}
dowhile语句格式:
do
{
       执行语句;
}while(条件表达式);
 
for(初始化表达式;循环条件表达式;循环后的操作表达式)
{
       执行语句;
}

注:

          a,for里面的连个表达式运行的顺序,初始化表达式只读一次,判断循环条件,为真就执行循环体,然后再执行循环后的操作表达式,接着继续判断循环条件,重复找个过程,直到条件不满足为止。

          b,while与for可以互换,区别在于for为了循环而定义的变量在for循环结束就是在内存中释放。而while循环使用的变量在循环结束后还可以继续使用。

          c,最简单无限循环格式:while(true) , for(;;),无限循环存在的原因是并不知道循环多少次,而是根据某些条件,来控制循环。

 

break(跳出), continue(继续)

break语句:应用范围:选择结构和循环结构。

continue语句:应用于循环结构。

注:a,这两个语句离开应用范围,存在是没有意义的。

b,这个两个语句单独存在下面都不可以有语句,因为执行不到。

c,continue语句是结束本次循环继续下次循环。

d,标号的出现,可以让这两个语句作用于指定的范围。

 if和switch的应用

          if的特点:

                    1,对具体的值进行判断。    例如星期123

                    2,对区间判断。   

                    3,对运算结果是boolean类型的表达式进行判断。

              switch   不常用,功能性较差,书写繁琐

                    1,对具体的值进行判断。          

                    2,值的个数通常是固定的

对比总结:    对于几个固定的值判断,建议使用switch语句,因为switch语句

             会将具体的答案都加载进内存,效率相对较高,其它情况用if语句比较好

  for和while的特点;

             1,for和while可以互换。

             2;格式上不同,使用上有一些区别

             while      循环结束后不会释放内存,变量x的值仍驻留在内存中

             for          循环结束,变量在内存中释放       性能优化,内存问题

 for和while的区别示例

            intx=1;
               while(x<5)
                    {
                           System.out.println("x="+x);
                           x++;
                    }
                    System.out.println("x===="+x);//x还在内存中,此时x=5,所以会输出x====5
             for(inty=1;y<5;y++)
             {
                    System.out.println("y="+y);
             }
             //System.out.println("y===="+y);// y的值已经被释放,所以此处会提示报错

 无限循环最简单的形式

             while(true){}

             for(;;){}

             循环结构的使用场景

             对某些代码执行很多次时,使用循环结构 

             对一个条件进行一次判断时 if

             当对一个条件进行多次判断时,使用while语句  

             注意事项

                    使用循环时,要明确哪些语句参与循环,那些不需要

                    循环通常情况下需要定义条件,控制次数

编程思想

         累加算法思想

例如:1~100数字的和

用while循环实现

        intx=1;         //记录参与加法的数据
             intsum=0;            //记录每一次的和
             while(x<=100)
             {
                    sum+=x;
                    x++;
             }

用for循环实现

                int sum=0;
                for(intx=1;x<=100;x++)
                {
                       sum=sum+x;
                }
               System.out.println("sum="+sum);

    计数器思想   

       例如:  统计1~100之间6的倍数出现次数

 用while循环实现

	intx=1;
             int count=0;
             while(x<=100)
             {
                    if(x%6==0)
                           count++;
                    x++;
             }

用for循环实现
   

             int count=0;
                for(intx=1;x<=100;x++)
                {
                       if (x%3==0)
                       count++;
                }
               System.out.println("count="+count); 

break(跳出),  continue(继续) ,return(返回值)
break语句:应用范围:选择结构和循环结构。
continue语句:应用于循环结构。
return语句:用在函数中,返回执行结果给调用者
注:
a,这两个语句离开应用范围,存在是没有意义的。
b,这个两个语句单独存在下面都不可以有语句,因为执行不到。
c,continue语句是结束本次循环继续下次循环。
d,标号的出现,可以让这两个语句作用于指定的范围。

break:跳出。
break作用的范围:要么是switch语句,要么是循环语句。

break跳出所在的当前循环。

用法示例:

		for(int x=0; x<3; x++)
		{
			if(x==1)
				break;//记住:当break语句单独存在时,下面不要定义其他语句,因为执行不到。
			System.out.println("x="+x);//如果没有if判断,这句话就执行不到
		}
		
		xiaoqiang:for (int x=0; x<3 ;x++ )//标号
		{
			wangcai:for (int y=0; y<4 ; y++)
			{
				System.out.println("x="+x);
				break xiaoqiang;//如果未命名break跳出所在的当前循环。命名则跳出指定循环
<span style="white-space:pre">			</span>}//如果出现了循环嵌套,break想要跳出指定的循环,可以通过标号来完成。
<span style="white-space:pre">		</span>}

continue:继续。
作用的范围:循环结构。
continue:结束本次循环,继续下次循环。

用法示例:

		for (int x=0; x<11 ;x++ )
		{
			if(x%2==0)
				continue;
			System.out.println("x="+x);//如果continue单独存在时,下面不要有任何语句,因为执行不到。
		}
		*/
		xiaoqiang:for (int x=0; x<3 ;x++ )
		{
			wangcai:for (int y=0; y<4 ; y++)
			{
				System.out.println("x="+x);
				continue xiaoqiang;//结束本次内循环,继续外循环
			}			
		}

函数

函数的定义

l什么是函数?
函数就是定义在类中的具有特定功能的一段独立小程序。
函数也称为方法。
l函数的格式:
•修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,)
{
执行语句;
return 返回值;
}
返回值类型:函数运行后的结果的数据类型。如果没有具体的返回值,用void表示
参数类型:是形式参数的数据类型。
形式参数:是一个变量,用于存储调用函数时传递给函数的实际参数。
实际参数:传递给形式参数的具体数值。
return:用于结束函数。
返回值:该值会返回给调用者。
注意:返回值类型和参数类型没有直接关系

函数的特点

定义函数可以将功能代码进行封装

l便于对该功能进行复用
l函数只有被调用才会被执行
l函数的出现提高了代码的 复用性
l对于函数没有具体返回值的情况,返回值类型用关键字 void表示,那么该函数中的return语句如果在最后一行可以省略不写。
l注意:
函数中只能调用函数,不可以在函数内部定义函数。
定义函数时,函数的结果应该返回给调用者,交由调用者处理。

函数的应用

l两个明确
明确要定义的功能最后的结果是什么?
明确在定义该功能的过程中,是否需要未知内容参与运算
l示例:
需求:定义一个功能,可以实现两个整数的加法运算。
分析:
•该功能的运算结果是什么?两个数的和,也是一个整数(int)
•在实现该功能的过程中是否有未知内容参与运算?加数和被加数是不确定的。(两个参数int,int)
•代码:
int  getSum(int x,int y)
{
return x+y;
}

函数的重载(重点)

同一个类 同名 参数个数或类型不同

重载的概念
在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。
重载的特点:
与返回值类型无关,只看参数列表。
重载的好处:
方便于阅读,优化了程序设计。
重载示例:
//返回两个整数的和
  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;}

栈内存的特点:先进后出

数组

数组的定义格式:
格式1: //需要一个容器,但不明确容器中的具体数据
元素类型[] 数组名 = new 元素类型[元素个数或数组长度];
示例:int[] arr = new int[5]; 
格式2: // 存储已知的具体数据
元素类型[] 数组名 = new 元素类型[]{元素,元素,……};
int[] arr = new int[]{3,5,1,7};
int[] arr = {3,5,1,7};

多维数组(略)

数组的内存结构

Java程序在运行时,需要在内存中的分配空间。为了提高运算效率,有对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
栈内存
l 用于存储局部变量,当数据使用完,所占空间会自动释放。
堆内存
l 数组和对象,通过<strong>new</strong>建立的实例都存放在堆内存中。
l 每一个实体都有内存地址值
l 实体中的变量都有默认初始化值 0,0.0/0.0f,bolean false,char'\u0000'
l 实体不在被使用,会在不确定的时间内被垃圾回收器回收
方法区,本地方法区,寄存器

内存划分,局部代码块限定 局部变量 的生命周期  垃圾回收机制

内存图解

数组常见异常

数组脚标越界异常(ArrayIndexOutOfBoundsException)
int[] arr = new int[2];
System.out.println(arr[3]);
访问到了数组中的不存在的脚标时发生。
空指针异常(NullPointerException)
int[] arr = null;
System.out.println(arr[0]);
arr引用没有指向实体,却在操作实体中的元素时。

数组常见操作

数组的遍历

获取数组最大值

数组排序<选择排序 冒泡排序, 获取索引排序

将数组换换成字符串

有序数组 折半查找(二分查找)

查表法的使用

小扩展:数组任意位置任意长度元素的copy


class ArrayDemo 
{
	public static void main(String[] args) 
	{	
		int[] arr={127,52,90,98,106,85};//大括号!
//		int max=getMax_2(arr);
//		System.out.println("max="+max);		
//		printArray(arr);
//		selectSort(arr);
//		printArray(arr);
//		bubbleSort(arr);
		selectSort_2(arr);
		printArray(arr);	
	}

	
	//遍历数组的功能
	public static void printArray(int[] arr)
	{	
		System.out.print("[");
		for (int x=0;x<arr.length ;x++ )
		{
			if (x!=arr.length-1)			
				System.out.print(arr[x]+",");
			else
				System.out.println(arr[x]+"]");
		}
	}
	
	public static void swap(int arr[],int a,int b)//元素换位
	{
		int temp=arr[a];
		arr[a]	=arr[b];
		arr[b]	=temp;
	}

	//冒泡排序		<span style="color:#ff0000;">!面试!</span>
	public static void bubbleSort(int[] arr)
	{
		for(int x=0;x<arr.length-1;x++)
		{
			for (int y=0;y<arr.length-1-x ;y++ )
			{
				if (arr[y]>arr[y+1])
				{					
					swap(arr,y+1,y);
					/*
					int	temp=arr[y];
					arr[y]=arr[y+1];
					arr[y+1]=temp;
					*/
				}
			}
		}
	}
//冒泡排序2			<span style="color:#ff0000;">!面试!</span>
	public static void bubbleSort_2(int[] arr)
	{
		for(int x=arr.length-1;x>0;x--)
		{
			for (int y=0;y<x ;y++ )
			{
				if (arr[y]>arr[y+1])
				{	
					swap(arr,y,y+1);
					/*
					int	temp=arr[y];
					arr[y]=arr[y+1];
					arr[y+1]=temp;
					*/
				}
			}
		}
	}
<p>//	import java.util.*;	Array.sort(arr);<span style="white-space:pre">	</span>//开发时用<span style="font-family: Arial, Helvetica, sans-serif;">排序函数<span style="white-space: pre;">		</span><span style="font-family: arial; font-size: 13px; line-height: 20px;">希尔排序</span><span style="font-family: arial; font-size: 13px; line-height: 20px;">(Shell Sort)</span></span></p>

	//选择排序
	public static void selectSort(int [] arr)
	{
		for (int x=0;x<arr.length-1 ;x++ )
		{
			for (int y=x+1; y<arr.length ;y++ )
			{
				if(arr[x]>arr[y])
				{
					swap(arr,x,y);
					/*
					int temp = arr[x];
					arr[x]	= arr[y];
					arr[y]	=temp;
					*/
				}
			}
		}
	}

	//选择排序2	使用角标,每次排序只交换一次,优化性能!元素多的时候性能差别较大
	public static void selectSort_2(int[] arr)
	{
		for (int x=0;x<arr.length-1 ;x++ )
		{
			int  num = arr[x];
			int index= x;
			for (int y=x+1;y<arr.length ; y++)
			{
				if(num>arr[y])
				{
					num=arr[y];
					index=y;
				}
			}
			if(index!=x)
				swap(arr,x,index);
		}
	}

	/*
	获取数组组最大值
	思路
	1,需要进行比较,并定义变量记录住每次比较后较大的值
	2,对数组中元素进行遍历取出,和变量中记录的元素进行比较
		如果遍历到的元素大于变量记录的元素,就用变量记录住该大值 
	3,遍历结果,该遍历结果就是最大值

	定义一个功能来实现
	明确1,结果是数组元素	int
	明确2,数组未知内容

	*/
	public static int getMax(int[] arr)
	{
		//定义变量记录较大的值
		int maxElement=arr[0];//初始化不应为0,负数
		for(int x=1;x<arr.length;x++)
		{
			if(arr[x]>maxElement)
				maxElement=arr[x];//元素
		}
		return	maxElement;
	}

	public static int getMax_2(int[] arr)
	{
		int maxIndex=0;
		for(int x=1;x<arr.length;x++)
		{
			if(arr[x]>arr[maxIndex])
				maxIndex =x;//角标
		}
		return arr[maxIndex];//返回角标对应的元素
	}		
}
	
一个数组操作工具集合

import java.util.Arrays;
public class ArrayTest
{
	public static void main(String[] args) 
	{	
		int x=2;
		int y=5;
		int z=y-x;
		int[] src =new int[]{1,3,2,3,5,7,9,5};
		int[] dest=new int[y];

		System.out.println(ArrayTool.getMax(src));
		System.arraycopy(src,x,dest,0,y);
		System.out.println(Arrays.toString(dest));
	}
}

public class ArrayTool
{
	private ArrayTool(){}
	
	//求数组最大值
	public static int getMax(int[] arr)
	{
		int maxIndex=0;
		for (int x=1;x<arr.length ;x++ )
		{
			if(arr[x]>arr[maxIndex])
				maxIndex=x;
		}
		return arr[maxIndex];
	}

	public static void swap(int[] arr, int a,int b)//位置交换
	{
		int Temp =arr[a];
		arr[a]=arr[b];
		arr[b]=Temp;
	}
	//选择排序
	public static void slectSort(int[] arr)
	{
		for (int x=0;x<arr.length-1 ;x++ )
		{
			for(int y=x+1;y<arr.length;y++)
			{
				if (arr[x]>arr[y])
				swap(arr,x,y);
			}
		}
	}
//数组查找 获取索引
	public static int getIndex(int[] arr,int key)
		{
		for (int x=0;x<arr.length ;x++ )
		{
			if (arr[x]==key)
			return x;
		}
		return -1;
		}

	//将数组转换成字符串
	public static String arrToString(int[] arr)
		{
			String str="";
			for (int x=0;x<arr.length ;x++ )
			{
				str=str+arr[x]+",";
			}
			return str;
		}
}

小扩展:数组任意位置任意长度元素的copy

方法一:创建一个新的数组,使用循环,从原数组起始位置遍历赋值给新数组(略)

方法二:JAVA自带方法

System.arraycopy() 可以复制数组

从指定源数组中复制一个数组,复制从指定的位置开始到目标数组的指定位置结束 

Arrays.copyOf() 可以创建数组副本

import java.util.Arrays;
public class ArrayTest
{
	public static void main(String[] args) 
	{	
		int x=2;
		int y=5;
		int z=y-x;
		int[] src =new int[]{1,3,2,3,5,7,9,5};
		int[] dest=new int[y];

		System.out.println(ArrayTool.getMax(src));//调用上文数组工具
		System.arraycopy(src,x,dest,0,y);//从原数组src[]的 角标=x 位置开始复制y个元素到数组dest[]
		System.out.println(Arrays.toString(dest));
	}
}

面试题:二分查找的应用

/*
	给定一个有序数组,如果往该数组中存储一个元素,并保证这个数组还是有序的
	那么这个元素存储的角标如何如何获取?
	{11,13,15,17,19,34,45,67,88,109};
	
*/
import java.util.*;

class ArrayDemo5 
{
	public static void main(String[] args) 
	{
//		int[] arr ={14,10,4,75,6,56};
//		int	index = getIndex(arr,11);
		int[] arr={1,4,5,7,11,15,25,46,89,123};
		int index=halfSearch_2(arr,89);
		System.out.println("index="+index);
		
		int index1= Arrays.binarySearch(arr,46);//java特有方法,如果存在,插入的是具体的返回位置
							//如果不存在,返回值为: -插入点-1
		System.out.println("index1="+index1);
	}

	/*
	数组常见功能:查找	都适用
	*/
	public static int getIndex(int[] arr, int key)
	{
		for (int x=0;x<arr.length ;x++ )
		{
			if(arr[x]==key)
			return	x;
		}
		return -1;//数据为int型必须有返回值
	}

	//二分查找	折半查找	!必须是有序数组
	//三个变量	循环
	public static int halfSearch(int[]	arr,int	key)
	{
		int max,min,mid;
		min=0;
		max=arr.length-1;
		mid=(min+max)/2;

		while(arr[mid]!=key)
		{
			mid=(max+min)/2;

			if(key>arr[mid])
				min=mid+1;
			else if(key<arr[mid])
				max=mid-1;

			if(max<min)
				return -1;
		}
		return mid;
	}
	//下面这种方法更直观
	public static int halfSearch_2(int[] arr,int key)
	{
		int max,min,mid;
		min=0;
		max=arr.length-1;
		
		while (min<=max)
		{
			mid=(min+max)>>1;//位移运算相当于"/2"
			if(key>arr[mid])
				min=mid+1;
			else if(key<arr[mid])
				max=mid-1;
			else
				return mid;
		}
		//return -1;
		return min;//返回插入位置	!面试题!
	}
}

查表法的应用

什么时候使用数组呢?
如果数据出现了对应关系,而且对应关系一方是有序的数字编号,并作为角标使用,这时就必须要想到数组的使用。
将这些数据存储到数组中,根据运算结果作为角标直接去查询数组中对应的元素即可
这种方式:称为!查表法! 编程思想无序数组同样适用

class ArrayTest 
{
	public static void main(String[] args) 
	{
		toHex_2(68);
	}

	public static void	toHex_2(int num)
	{
		if(num=0)
		{
			System.out.println("0");
			return;		//这个return存在的意义,一旦满足条件下面的程序就不再执行
		}
		<span style="white-space:pre">		</span>//对应一个关系表
		char[] chs={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
		/*
		查表会查到比较多的数据,数据一多,就先存储起来,再进行操作;所以定义一个数组作为临时容器
		pos=0;	pos++
		pos=arr.length ; --pos 角标反转,从大角标逆序输出
		*/
//临时容器的使用!!!
		char[]	arr= new char[32];
		int	pos=arr.length;		//pos=0改成	用指针操作数组中的元素
		
		while (num!=0)
		{
			int temp=num&15;
			arr[--pos]=chs[temp];<span style="white-space:pre">	</span>//pos++改成--pos
			num=num>>>4;
		}
		System.out.println("pos="+pos);
		for (int x=pos;x< arr.length;x++ )
		{
			System.out.print(arr[x]+",");
		}
		return;<span style="white-space:pre">	</span>//这个return可以省略
	}
//查表法
	public static void	toHex_1(int num)
	{		<span style="white-space:pre">				</span>//对应一个关系表,无序数组同样适用
		char[] chs={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
		for (int x=0;x<8 ;x++ )
		{
			int temp=num&15;
			System.out.print( chs[temp] );
			num=num>>>4;
		}
	}
//一般方法
	public static void toHex(int num)
	{
		for (int x=0;x<8 ;x++ )
		{
			int temp=num&15;
			if(temp>9)
				System.out.print( (char)(temp-10+'A') );//print(char)强转
			else
				System.out.print(temp);
			num=num>>>4;
		}
	}
}

查表法拓展,进制转换工具

class ArrayTest //进制转换

{
	public static void main(String[] args) 
	{
		toHex(60);
		toBinary(60);
		toOctal(60);
	}
	//十进制-->十六进制
	public static void toHex(int num)
	{
		trans(num,15,4);
	}
	//十进制-->八进制
	public static void toBinary(int num)
	{
		trans(num,7,3);
	}
	//十进制-->二进制
	public static void toOctal(int num)
	{
		trans(num,1,1);
	}

//转换方法封装
	public static void trans(int num,int base, int offset)
	{
		if(num==0)
		{
			System.out.println("0");
			return;		
		}

		char[] chs={'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 ;		//将位运算定义为变量
		}

		System.out.println("pos="+pos);
		for (int x=pos;x< arr.length;x++ )
		{
			System.out.print(arr[x]+",");
		}
	}
}

本章小结:

对于初学者而言,语法基础应该重视起来,不能盲目的贪功冒进,试想你写了几十行的小程序,一下子弹出十几个错误,光调试排错就要花掉比你写程序更多的时间,显然是得不偿失的,因为本人就亲身有过这样的经历~⊙﹏⊙b汗

尤其是对于JAVA这种强类型语言养成严谨规范的代码风格,能够在以后的学习中避免许多不必要的错误,提高学习效率和质量



  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值