天天看點

黑馬程式員 Java初級<三>---> 程式流程控制與函數

和其他程式設計語言一樣,java中的程式流程控制是通過:條件語句、選擇語句以及循環語句來控制的。具體總結如下:

在總結每一種語句之前,先說明一個知識點:語句塊。

語句塊:

也稱作用域,是指由一對花括号(即{ })括起來的若幹條語句。語句塊确定了成員的作用域,表示這些語句的使用範圍。當然,語句塊中還可以嵌套其他語句塊。

第一節   判斷結構

一、格式:

判斷結構是if語句,它有三種結構:

1、格式一:

if (布爾型表達式)
{
	執行語句
}
           

如果布爾型表達式的值為true(或者說條件為真),則執行{}中的語句,否則不執行。

2、格式二:

if (布爾型表達式)
{
	執行語句1
}
else
{
	執行語句2	
}
           

如果布爾型表達式的值為true(或者說條件為真),則執行if後{}中的語句1,否則執行else後{}中的語句2。

3、格式三:

if (布爾型表達式1)
{
	執行語句1
}
else if (布爾型表達式2)
{
	執行語句2	
}
else
{
	執行語句3
}
           

如果布爾型表達式1的值為true(或者說條件為真),則執行if後{}中的語句1,然後退出這個結構;不滿足的話,檢查是否滿足布爾型表達式2,滿足的話就執行else if後{}中的語句2,然後退出這個結構,否則就執行語句3。

二、關于三元運算符:

注:if語句的簡寫格式為三元運算符,即(布爾型表達式)?表達式1:表達式2。

三元運算符:

好處:可以簡化if else代碼的書寫,

弊端:因為是一個運算符,是有傳回值的,必須有接收這個傳回值的變量。而if語句運算完可無需結果。

注意:三元運算符的表達式1和2必須有相同的類型。

示例:

class DemoIf 
{
	public static void main(String[] args) 
	{
		int x = 5;
		if (x>0)
		{
			System.out.println("3/x是可以的,結果為正數。")
		}
		else if (x < 0)
		{
			System.out.println("3/x是可以的,結果為負數。")
		}
		else
		{
			System.out.println("别想了,3/x是不可以的。");
		}
	}
}
           

第二節   選擇結構

一、格式:

switch (表達式)
{
	case 取值1: 
		執行語句;
		break;
	case 取值2: 
		執行語句;
		break;
	 ......
	default :
		執行語句;
		break;
}
           

二、switch特點:

1、表達式不可為布爾型表達式

2、case的取值隻能為byte、short、int、char以及字元串、枚舉等六種類型,

注:在JDK1.5中還因為出現了枚舉,也可以在switch中應用此類型。

3、case與default沒有必然的順序,要先執行case,執行從上向下執行,沒有找到比對的case執行default。

4、結束switch語句的兩種情況:遇到break或者執行到switch結尾結束。

5、如果沒有break,每個case都會判斷一次,如果不符合表達式的值,則繼續判斷下面的case取值,如果滿足表達式的值,執行完目前語句後,會繼續判斷并執行後面全部的語句,直到switch語句結束。

三、if和switch的選擇:

1、選擇if:運算結果為布爾型的,含有判斷區間的,或其他情況下使用if。使用範圍更廣。

2、選擇switch:判斷少量具體數值,類型僅為byte、short、int和char和字元串的時候。因為當加載switch的時候,這些資料會全進記憶體。效率相對if高一些。

示例:

class DemoSwitch
{
	public static void main(String[] args) 
	{
		int x = 5;
		switch (x)
		{
			case 3:
			case 4:
			case 5:
				System.out.println("夏季。");
				break;
			case 6:
			case 7:
			case 8:
				System.out.println("秋季。");
				break;
			case 9:
			case 10:
			case 11:
				System.out.println("冬季。");
				break;
			case 12:
			case 1:
			case 2:
				System.out.println("春季。");
				break;
			default :
				System.out.println("無。");
				break;
		}
	}
}

           

第三節   循環結構

對于循環結構,有三種形式:while、do while、for。

一、while循環

格式:

定義初始化表達式;
		while (條件表達式)
		{
			循環體(執行語句);
		}
           

先判斷表達式是否為true,每次判斷如果都為真,那麼就執行,直到不符合表達式,為false的時候退出循環。

二、do while循環

格式:

定義初始化表達式;
		do
		{
			循環體(執行語句);
		}
		while (條件表達式)
           

特點:先執行一次循環體,然後再進行判斷,如果滿足繼續,不滿足退出。循環體至少被執行一次。

三、for循環

1、格式:

//格式一
	for (初始化表達式;循環條件表達式;循環後操作表達式)
	{
		執行語句;
	}

	//格式二
	初始化表達式;
	for (;循環條件表達式;)
	{
		執行語句;
		(循環後操作表達式)
	}
           

說明:對于格式一,初始化表達式中如果有變量,是局部變量,存在于棧記憶體中,循環結束,随之消亡。而對于格式二,則不同,作用域是存在于for外面的語句塊中。 注:初始化表達式隻讀一次,判斷是否滿足循環條件表達式,滿足則進行循環。

四、無限循環的最簡單形式:

for(;;){}

while(true){}

第四節   循環的選擇

一、對于for循環和while循環的使用:

對于變量:變量有自己的作用域,如果将控制循環的增量定義在for語句中,那麼變量隻在for循環中作用,for循環結束,該變量在記憶體中被釋放。

對于循環的選擇:

先看一看一個小程式需求:Hotpo遊戲:

Hotpo是Half Or Triple Plus One(半數或3倍加1)的簡寫。規則為:一個自然數,如果是偶數,就減去它的一半;如果是奇數,就3倍這個數再加1。一直這樣計算下去,直到值到達1。

編寫一個程式,設定一個初始值,并讓這個循環列印這個序列中的每個數,連同目前步驟号,如3的輸出結果将是:

       Step #1: 10

       Step #2: 5

       Step #3: 16

       Step #4:  8

       Step #5:  4

       Step #6:  2

       Step #7:  1

那麼,這個程式應該使用一個for循環,還是使用一個while循環呢?

我想,大家在用for循環寫程式的時候就會發現,for中的條件确定為多少呢。好,這就引出了我這篇文章的主題了:

當我們事先知道将要對該循環的主體循環多少次的時候,最好是使用for循環,這樣for中的條件就可以确定了。如果在循環執行完之前一直不知道主體循環了多少次,那麼,現在最好就要用while了。當然,我們同樣可以用兩個循環完成某些程式,這沒有錯與對的分别,隻有更合适與否之分。

好啦,下面是我為大家分享的一段程式:

class TestLoop
{
	public static void main(String [] args)
	{
	    int n = 3;
	    int nStep = 0;
	    while(n !=1)
	    {
	       n = (n%2==0)? (n/2) : (3*n+1);
		nStep++;
		System.out.println("Step #"+nStep+": "+n);
	    }
       }
}
           

大家看到之後都會覺得很熟悉這個問題,這其實就是角谷猜想,隻不過角谷猜想是驗證是否3到10000之間的自然數都符合這個結果。下面是我為大家分享的角谷猜想的程式:

public class Jiaogu
{
	static int count;
	public static void main(String[] args) {
		int num = 10000;
		for (int i = 3; i <= num; i++)
		    dispose(i);
		System.out.println(count == (num - 3 + 1));
	}
	public static void dispose(int i) {

		i = (i % 2 == 0)?(i / 2):(i * 3 + 1);
		if (i != 1) {
		     dispose(i);
		} 
		else {
		     count++;
		}
	}
}
           

補充:

請看下面的代碼:

class Xunhuan
{
	public static void main(String [] args)
	{
		for(int i=0;i<3;i++)
		{
			System.out.println("i = " + i);
		}
		System.out.println("i = " + i);
		
		int j = 0;
		while(j < 3)
		{
			System.out.println("j = " + j);
		}
		System.out.println("j = " + j);

		int m=0;
		for(;m<3;m++)
		{
			System.out.println("m = " + m);
		}
		System.out.println("m = " + m);
		
	}
}
           

運作後會報錯:

黑馬程式員 Java初級&lt;三&gt;---&gt; 程式流程控制與函數

因為變量i是在for中定義的,隻能存在于for中,當for循環結束後,i會被銷毀,不再存在于記憶體之中,是以記憶體會得到優化。而while循環中的j是依然存在的,因為j是在循環外定義的。是以:

如果變量隻是作為循環中的增量存在,控制循環的次數,那麼,用for循環式更好些的,利于記憶體的優化。如果此變量在後面的程式中仍然需要,用while較好;當然,也可以用for循環,隻是要像第三個循環一樣,将變量定義在for循環之外,同樣是可行的。

第五節   函數

一、函數的概述:

函數也稱為方法,是定義在類中的具有特定功能的一段獨立的小程式。函數可以實作某些特定的功能。

1、定義函數的展現:

在寫程式時,發現運算中擷取不同資料的運算結果,總是重複使用一些代碼,為了提高代碼的複用性,就對代碼進行了抽取。

将這個抽取的部分定義為一個獨立的功能,友善日後重複使用。這就是函數的展現形式。

2、函數的格式:

修飾符 傳回值類型 函數名(參數類型 形式參數1,參數類型 形式參數2,......)
{
	執行語句;
	return 傳回值;
}
           

傳回值類型:函數運作後的結果的資料類型

參 數  類 型:是形式參數的資料類型,就是傳入的資料的類型

形 式  參 數:是一個變量,用于存儲調用函數時傳遞給函數的實際參數

實 際  參 數:傳遞給形式參數的具體數值

return          :用于結束函數運作的語句,表示函數執行完畢

返   回   值  :該值将傳回給調用者,即函數實作功能需要獲得的資料。

說明:當函數運作完,沒有具體的傳回值,這時的傳回值類型可以用一個特殊的關鍵字來表示,即void,它代表的是函數沒有具體的傳回值的情況。此時,函數中的return可以省略不寫。

3、何時定義函數:

1)首先要明确函數的功能,這個功能實作的運算結果是什麼

       其實就是在明确傳回值類型

2)在定義函數功能的過程中需要明确是否含有位置内容參與運算

      其實就是在明确函數的參數清單(參數類型和參數個數)

示例:

/*
	需求:列印a ~ b 中每個數與c的乘積
	分析:明确功能的結果:列印運算結果,傳回類型無,為void
		  在實作功能的過程中是否有位置内容:有,int型的a、b和c

	*/
	public static void Chengji(int a,int b,int c)
	{
		int j = 1;
		for(a=1;a<=b;a++)
		{
			int m = c*a;
			System.out.print(m + "\t");
			if(j == a/10)//十個數換一次行
			{  
				j++;
				System.out.println(" ");
			}
		}
	}
           

二、函數的特點:

1、定義函數可以将功能代碼進行封裝,展現了java的封裝性

2、定義函數可以提高代碼的複用性,便于使用,可對功能進行複用

3、函數需要被調用才能被執行,否則就是一段代碼

4、無傳回值類型的函數用void修飾,則可以省略函數中的return

5、函數中不可以定義函數(内部類除外),但函數間可以互相調用。

三、函數的重載:

1、定義:在同一個類中,允許存在一個以上的同名函數,隻要他們的參數個數或者參數類型不同即可。

2、特點:與傳回值類型無關,隻看參數清單。

3、好處:友善與閱讀,優化了程式設計。

4、重載解析:編譯器對于重載的方法會進行選擇,,比對出相應的方法,如果編譯器找不到比對的參數,或者找出了多個可能的比對函數,那麼就會産生編譯錯誤。

示例:

//定義函數,求兩個數的和
public static int add(int a,int b)
{
	return a+b;
}

//定義函數,求三個數的和
public static int addT(int a,int b,int c)
{
	return add(a,b)+c;
}