黑马程序员:函数

------- android培训java培训、期待与您交流! ----------

2.7函数


(1)函数定义

1)什么是函数?

函数就是定义在类中的具有特定功能的一段独立小程序。函数也称为方法。
发现很多的运算,因为获取不同数据的运算结果,代码出现了重复。
为了提高代码的复用性。对代码进行抽取。
将这个部分定义成一个独立的功能。方便与日后使用。
java中对功能的定义是通过函数的形式来体现的。
注意:是独立的程序。

2)函数的格式:

修饰符 返回值类型 函数名(参数类型形式参数1,参数类型形式参数2,)
{
执行语句;
return 返回值;
}

返回值类型:函数运行后的结果的数据类型。
参数类型:是形式参数的数据类型。
形式参数:是一个变量,用于存储调用函数时传递给函数的实际参数。
实际参数:传递给形式参数的具体数值。
return:用于结束函数。
返回值:该值会返回给调用者。

当函数运算后,没有具体的返回值时,这是返回值类型用一个特殊的关键字来标识。
该关键字就是void。void:代表的是函数没有具体返回值的情况。
当函数的返回值类型是void时,函数中的return语句可以省略不写。

-------------------------------------------------

(2)函数特点

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

便于对该功能进行复用

函数只有被调用才会被执行

函数的出现提高了代码的复用性

对于函数没有具体返回值的情况,返回值类型用关键 字void表示,那么该函数中的return语句如果在最后一行可以省略不写。

关键:函数进行封装、提高复用、需要调用。

注意:
函数中只能调用函数,不可以在函数内部定义函数。

定义函数时,函数的结果应该返回给调用者,交由调用者处理。

-------------------------------------------------

(3)函数应用(重点)

如何定义一个函数呢?
1,既然函数是一个独立的功能,那么该功能的运算结果是什么先明确
因为这是在明确函数的返回值类型。
2,在明确在定义该功能的过程中是否需要未知的内容参与运算。
因为是在明确函数的参数列表(参数的类型和参数的个数)。


简而言之:
两个明确
明确要定义的功能最后的结果是什么?也就明确返回值类型,和返回值。

明确在定义该功能的过程中,是否需要未知内容参与运算。也就明确参数列表。

示例:
需求:定义一个功能,可以实现两个整数的加法运算。

分析:
该功能的运算结果是什么?两个数的和,也是一个整数(int)


在实现该功能的过程中是否有未知内容参与运算?加数和被加数是不确定的。(两个参数int,int)


代码:
int getSum(int x,int y)
{
return x+y;

}

实例:

<span style="font-size:18px;">class FunctionDemo 
{
public static void main(String[] args) 
{
/*
int x = 4;
System.out.println(x*3+5);
x = 6;
System.out.println(x*3+5);
*/
getResult(5);


}
/*
需要定义功能,完成一个整数的*3+5的运算,
当函数运算后,没有具体的返回值时,这是返回值类型用一个特殊的关键字来标识。
该关键字就是void。void:代表的是函数没有具体返回值的情况。
当函数的返回值类型是void时,函数中的return语句可以省略不写。
*/
public static void getResult(int num)
{
System.out.println(num * 3 + 5);
return;//可以省略
}
}


/*
需求:判断两个数是否相同。
思路:
1,明确功能的结果:结果是:boolean 。
2,功能是否有未知内容参与运算。有,两个整数。
*/
public static boolean compare(int a,int b)
{
/*
if(a==b)
return true;
//else
return false;
*/


//return (a==b)?true:false;


return a==b;
}


/*
需求:定义功能,对两个数进行比较。获取较大的数。
*/
public static int getMax(int a,int b)
{
/*
if(a>b)
return a;
else
return b;
*/
return (a>b)?a:b;
}
}</span>

-------------------------------------------------

(4)函数重载



重载:在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。
也就是说重载只和参数类表有关。


重载的特点:
与返回值类型无关,只看参数列表。

重载的好处:
方便于阅读,优化了程序设计。

重载示例:
//返回两个整数的和
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;}

什么时候用重载?
当定义的功能相同,但参与运算的未知内容不同。
那么,这时就定义一个函数名称以表示起功能,方便阅读,而通过参数列表的不同来区分多个同名函数。

重载练习:
void show(int a,char b,double c){}
a.
void show(int x,char y,double z){}//没有,因为和原函数一样。

b.

int show(int a,double c,char b){}//重载,因为参数类型不同。注意:重载和返回值类型没关系。


c.

void show(int a,double c,char b){}//重载,因为参数类型不同。注意:重载和返回值类型没关系。

d.
boolean show(int c,char b){}//重载了,因为参数个数不同。

e.
void show(double c){}//重载了,因为参数个数不同。

f.
double show(int x,char y,double z){}//没有,这个函数不可以和给定函数同时存在与一个类中。

实例:
<span style="font-size:18px;">public static void print99(int num)
	{
		for(int x=1; x<=num; x++)
		{
			for(int y=1; y<=x; y++)
			{
				System.out.print(y+"*"+x+"="+y*x+"\t");
			}
			System.out.println();
		}
	}
	//打印99乘法表
	public static void print99()
	{
		print99(9);
	}
	


	//定义一个加法运算,获取两个整数的和。
	public static int add(int x,int y)
	{
		return x+y;
	}

	//定义一个加法,获取三个整数的和。
	public static int add(int x,int y,int z)
	{
		return add(x,y)+z;//add(x,y)在原有基础上进行修改
	}</span>

-------------------------------------------------

2.8数组

(1)数组的定义

同一种类型数据的集合。其实数组就是一个容器(能存数据的地方,装东西,东西就是元素,元素的类型要同一种类型)。

运算的时候,有可能会有很多数据参与运算,首先,把这些数据存储起来,以便于后期运算,数组就是存储数据的一种方式。

数组的好处
可以自动给数组中的元素从0开始编号,方便操作这些元素。

格式1:
元素类型[] 数组名= new 元素类型[元素个数或数组长度];
示例:
需求:想定义一个可以存储3个整数的容器。
int[] x = new int[3];

new int[3]在内存中定义了一个真实存在的数组,能存储3个元素,为了方便使用,定义了一个名称x。

3不是元素,是元素的个数。x 不是int型,是数组类型的,

格式2:
元素类型[] 数组名= new 元素类型[]{元素,元素,……};
int[] arr = new int[]{3,5,1,7};
int[] arr = {3,5,1,7};

-------------------------------------------------

(2)数组的内存分配及特点

Java程序在运行时,需要在内存中的分配空间。为了提高运算效率,有对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内 存管理方式。

java在内存中一共划分了5片空间,分别是栈内存,堆内存,方法区,本地方法区,寄存器。

栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放。
局部变量:定义在方法中,定义在循环中的变量,都是局部变量。

堆内存:数组和对象,通过new建立的实例都存放在堆内存中。

每一个实体都有内存地址值,实体中的变量都有默认初始化值

实体不在被使用,会在不确定的时间内被垃圾回收器回收

堆内存特点:(1)堆内存地址值 (2)堆内存中变量,都有默认初始化值 (3)垃圾回收机制

注意:不想让x指向数组,x = null;x不再指向数组,值为空。

当一个实体在堆内存中,没有任何一个引用使用它的话,就是java虚拟机的垃圾。
垃圾不会被及时清理,而是在不定时的时候,启动垃圾回收机制,将数组实体在堆内存中清除。

java垃圾回收机制:c++垃圾回收机制,需要程序员手动调用。而java优化了垃圾回收机制,虚拟机会自动使用垃圾回收机制清除垃圾。

实例:
int[] x = new int[3];

栈 x

堆 new int[3];  //凡是new出来的实体都在堆里面,产生一个地址

x只是拥有堆中 数组的地址。

-------------------------------------------------

(3)数组操作常见问题

数组脚标越界异常(ArrayIndexOutOfBoundsException)
int[] arr = new int[2];
System.out.println(arr[3]);

ArrayIndexOutOfBoundsException 代表访问到了数组中的不存在的脚标时发生。

空指针异常(NullPointerException)
int[] arr = null;
System.out.println(arr[0]);
arr引用没有指向实体,却在操作实体中的元素时。

NullPointerException:空指针异常:当引用没有任何指向值为null的情况,该引用还在用于操作实体。

-------------------------------------------------

(4)数组常见操作

获取元素。获取数组中的元素。通常会用到遍历。

实例:

int[] arr = {3,6,5,1,8,9,67};

//数组中有一个属性可以直接获取到数组元素个数。length.
//使用方式:数组名称.length = 
//System.out.println("length:"+arr.length);

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

-------------------------------------------------

获取最值(最大值,最小值)

实例:

<span style="font-size:18px;">class ArrayTest 
{

	/*
	获取数组中的最大值。
	思路:
	1,获取最值需要进行比较。每一次比较都会有一个较大的值。因为该值不确定。
	通过一个变量进行临储。
	2,让数组中的每一个元素都和这个变量中的值进行比较。
	如果大于了变量中的值,就用该该变量记录较大值。
	3,当所有的元素都比较完成,那么该变量中存储的就是数组中的最大值了。

	步骤:
	1,定义变量。初始化为数组中任意一个元素即可。
	2,通过循环语句对数组进行遍历。
	3,在变量过程中定义判断条件,如果遍历到的元素比变量中的元素大,就赋值给该变量;
	
	需要定义一个功能来完成。以便提高复用性。
	1,明确结果,数组中的最大元素 int。、
	2,未知内容:一个数组。int[]
	*/
	public static int getMax(int[] arr)
	{
		int max = arr[0];

		for(int x=1; x<arr.length; x++)
		{
			if(arr[x]>max)
				max = arr[x];
		}
		return max;
	}


	/*
	获取最大值的另一种方式。
	可不可以将临时变量初始化为0呢?可以。这种方式,其实是在初始化为数组中任意一个角标。


	*/
	public static int getMax_2(int[] arr)
	{
		int max = 0;

		for(int x=1; x<arr.length; x++)
		{
			if(arr[x]>arr[max])
				max = x;
		}
		return arr[max];
	}


	/*
	获取最小值。
	*/
	public static int getMin(int[] arr)
	{
		int min = 0;
		for(int x=1; x<arr.length; x++)
		{
			if(arr[x]<arr[min])
				min = x;
		}
		return arr[min];
	}

	//获取double类型数组的最大值。因为功能一致,所以定义相同函数名称。以重载形式存在。
	/*
	public static double getMax(double[] arr)
	{
		
	}
	*/
	public static void main(String[] args)
	{
		int[] arr ={5,1,6,4,2,8,9};

		int max = getMax_2(arr);
		int min = getMin(arr);
		System.out.println("max="+max);
		System.out.println("min="+min);
	}

}</span>
注意:
boolean[] ar = new boolean[3];
System.out.println(ar[1]);

数组默认值为 false

-------------------------------------------------

排序(选择排序,冒泡排序)

<span style="font-size:18px;">import java.util.*;
/*
对给定数组进行排序。
{5,1,6,4,2,8,9}


*/
class ArrayTest2 
{

	/*
	选择排序。
	内循环结束一次,最值出现头角标位置上。
	*/
	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])
				{
					/*
					int temp = arr[x];
					arr[x] = arr[y];
					arr[y]= temp;
					*/
					swap(arr,x,y);
				}
			}
		}
	}
	/*
	冒泡排序
	*/

	public static void bubbleSort(int[] arr)
	{
		for(int x=0; x<arr.length-1; x++)
		{									
			for(int y=0; y<arr.length-x-1; y++)//-x:让每一次比较的元素减少,-1:避免角标越界。
			{
				if(arr[y]<arr[y+1])
				{
					/*
					int temp = arr[y];
					arr[y] = arr[y+1];
					arr[y+1] = temp;
					*/
					swap(arr,y,y+1);
				}
			}
		}
	}

	/*
	发现无论什么排序。都需要对满足条件的元素进行位置置换。
	所以可以把这部分相同的代码提取出来,单独封装成一个函数。
	*/
	public static void swap(int[] arr,int a,int b)
	{
		int temp = arr[a];
		arr[a] = arr[b];
		arr[b] = temp;
	}
	public static void main(String[] args)
	{
		int[] arr = {5,1,6,4,2,8,9};
		//排序前;
		printArray(arr);

		//排序
		//selectSort(arr);
		//bubbleSort(arr);

		//Arrays.sort(arr);//java中已经定义好的一种排序方式。开发中,对数组排序。要使用该句代码。
		//排序后:
		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]+"]");

		}		
	}
}</span>

-------------------------------------------------

折半查找(二分查找)

总结:就是对有序数组,取位于数组中间位置的数,进行比较,如果小于,就以中间位置为min,再取一个中间位置的数进行比较;如果大于,就以就以中间位置为max,再取一个中间位置的数进行比较。一直到min和max的位置一致,循环结束。

实例:

<span style="font-size:18px;">//普通遍历查找

	//定义功能,获取key第一次出现在数组中的位置。如果返回是-1,那么代表该key在数组中不存在
	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 int halfSearch(int[] arr,int key)
	{
		int min,max,mid;
		min = 0;
		max = arr.length-1;
		mid = (max+min)/2;

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

			if(min>max)
				return -1;
			mid = (max+min)/2;
		}
		return mid;
	}

</span>

-------------------------------------------------

<span style="font-size:18px;">/*
	折半的第二种方式。
	*/
	public static int halfSearch_2(int[] arr,int key)
	{
		int min = 0,max = arr.length-1,mid;

		while(min<=max)
		{
			mid = (max+min)>>1;

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

-------------------------------------------------

(5)数组中的数组(小知识点)

数组是用来存数据,只要是识别的数据类型都能往里存。往数组里存的还是数组,把数组作为元素。

比喻:大箱子里有格子,每个格子里放的是元素。现在是大箱子里有小箱子,每个小箱子里有格子。

二维数组[][]

实例:

int[][] arr = new int[3][4];
//定义了名称为arr的二维数组。二维数组中有3个一维数组。
//每一个一维数组中有四个元素。

int[][] arr  = new int[3][];

arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];

System.out.println(arr.length);//打印是二维数组的长度 3;
System.out.println(arr[0].length);//打印二维数组中第一个一维数组长度

另一种方法:
int[][] arr = {{3,5,1,7},{2,3,5,8},{6,1,8,2}};

int sum = 0;
for(int x=0; x<arr.length;x++)
{
for(int y=0; y<arr[x].length; y++)
{
sum = sum + arr[x][y];
}
}

System.out.println("sum="+sum);


-------------------------------------------------

什么时候用二维数组?

数据多了,需要进行容器的存储。数据之间有关系,有关系的数据,封装到一个数组。但是,有很多组,一个公司很多部门,都是公司的元素。把这些元素再封装到一个组里面去,就是二维数组。

举例:
公司有3个小组。
{ {} {} {} }
每个组有具体的数据
{2,4} {2,4} {2,4}

-------------------------------------------------

实例:获取二维数组和

<span style="font-size:18px;">int[][] arr = {{3,5,1,7},{2,3,5,8},{6,1,8,2}};

int sum = 0;
for(int x=0; x<arr.length;x++)
{
	for(int y=0; y<arr[x].length; y++)
	{
		sum = sum + arr[x][y];
	}
}

	System.out.println("sum="+sum);
}</span>

-------------------------------------------------

二维数组小练习:

int[] x; int x[];
int[][] y; int y[][]; int[] y[];

int[] x,y[];//x一维,y二维。
int[] x;
int[] y[];


a.

x[0] = y;//error

b.
y[0] = x;//yes


c.

y[0][0] = x;//error

d.
x[0][0] = y;//error

e.
y[0][0] = x[0];//yes

f.
x=y;//error

-------------------------------------------------


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值