第三章 條件語句、迴圈與方法
一、概述
流程控制語句是用來控制程式中各語句執行順序的語句,可以把語句組合成能完成一定功能的小邏輯模組。其流程控制方式採用結構化程式設計中規定的三種基本流程結構,即:順序結構、分支結構和迴圈結構。
二、選擇結構
2.1條件語句if
if分支結構分為三種:if、if else、if-if else。結構不同,優缺點不同。
2.1.1 if和else
Scanner sc = new Scanner(System.in); System.out.println("請輸入一個整數:"); int num = sc.nextInt(); if( num % 2 == 0 ){ System.out.println("您輸入的"+num+",是一個偶數"); }else{ System.out.println("您輸入的"+num+",是一個奇數"); }
單/雙分支語句:if(){};結構:()放入一個結果是true或false的值,在{}中寫滿足條件需要執行的程式碼。else{}的{]中寫不滿足條件需要執行的程式碼。
2.1.2 if -else if
if( num >=90 ){ System.out.println("您得到的等級是:A級"); }else if( num >=80 ){ System.out.println("您得到的等級是:B級"); }else if( num >=70 ){ System.out.println("您得到的等級是:C級"); }else if( num >=60 ){ System.out.println("您得到的等級是:D級"); }else{ System.out.println("您得到的等級是:E級"); }
多分支語句:if(){}else if(){};else if可以翻譯為否則如果,如果num>=90,否則如果num>=80,依次判斷下去。當執行到滿足條件的語句時,將不再執行後續條件語句。
2.2條件語句switch
int num2 = num / 10; switch(num2){ case 9: System.out.println("您得到的等級是:A級"); break; case 8: System.out.println("您得到的等級是:B級"); break; case 7: System.out.println("您得到的等級是:C級"); break; case 6: System.out.println("您得到的等級是:D級"); break; default: System.out.println("您得到的等級是:E級"); }
執行過程:首先拿表示式中值與case中的值逐個比較,如果case值相等,則執行對應語句,執行後會執行break結束比較,防穿透。如果沒有break,會無條件的執行下面的表示式,如果沒有case對應的值,會執行default下的語句。default語句可以寫在任意位置,但是一般情況放在最後。default就是如果沒有符合的case就執行它,default並不是必須的。
switch語句只能做整數、字元型、列舉、1.7版本之後可以做String型別的資料比較。
三、迴圈結構
迴圈三要素:迴圈變數賦初值,迴圈條件合理(boolean型的結果),迴圈變數要改變,不一定是加減,只要改變就行。迴圈結構都由如下四個結構組成:初始化、條件判斷、迴圈體、迭代。
3.1while
Scanner sc = new Scanner(System.in);
System.out.println ("請輸入一個正整數");
int num = sc.nextInt();
//先判斷是否為正數
if(num >= 0){
//判斷是否為偶數
if(num <= 2){
System.out.println (num+"不是素數");
return;
}
int i = 2;
//定義i為2 輸入的數字每次向i++求餘,當餘數為0時跳出whule迴圈
while( num % i != 0 ){
i++;
}
//餘數為0分為兩種情況,一種是模到自己本身,即num==i此時便是素數
//第二種情況是模到自己的因數,即能被除自身和1以外的數整除,不是素數。
if(num == i ){
System.out.println (num+"是素數");
}else{
System.out.println (num+"不是素數");
}
}else{
System.out.println ("不能為負數");
}
while是入口迴圈,先判定後執行,執行0-n次。在迴圈剛開始時,會計算一次表示式的值,弱條件為真,執行迴圈體。而對於後來每一次額外的迴圈,都會在開始前重新計算一次。語句中應有使迴圈趨向於結束的語句,否則會出現無限迴圈——“死”迴圈。
3.2do-while
Scanner sc = new Scanner(System.in);
//先宣告一個char型變數,假定num2的值為y
char num2 = 'y';
//先執行,再判斷
//在這裡num2即是初始值,也做了改變。
do{
System.out.println ("請輸入一個整數");
int num1 = sc.nextInt();
System.out.println ("您輸入的整數是:"+num1);
System.out.println ("是否繼續列印");
num2 = sc.next().charAt(0);
//進行判斷
}while( num2 == 'y' || num2 == 'Y');
while:先判斷,後執行。do-while先執行,後判斷。
3.3for
public static void main(String[] args){
//這裡素數不可能是偶數,所以直接賦初始值為101,每次加2,保證i一直為奇數,這樣可以減少迴圈次數
for ( int i = 1 ; i <= 99 ; i+=2 ){
//這裡可以執行一個空迴圈,只要變數j逐一增加就可以了,在這裡j需要定義在for迴圈之外,因為下面的if中還要用到j變數
int j ;
for( j = 2 ; (i % j != 0) && ( j <= 99) ; j++ ){
}
//無論是素數還是不是素數i%j都會得到一個0的答案,所以接下來要做的就是判斷i%j等於0,屬於哪一種情況,如果i==j說明i%的這個j是他本身,所以當i==j時,i為素數,打印出素數
if( i == j ){
System.out.println (i);
}
}
}
for迴圈語句是支援迭代的一種通用結構,是最有效、最靈活的迴圈結構。
注意事項:for迴圈再執行條件測試後,先執行程式部分,再執行步進。在for語句的初始化部分宣告的變數,其作用域為整個for迴圈體。“初始化”和“迴圈條件表示式”部分可以使用逗號來執行多個操作。如果三個部分都為空語句(分號不能省),相當於一個無限迴圈。
3.4跳轉
public class Bbreak{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
//break是結束包含它的迴圈,並且該迴圈的後續程式碼不再執行
//一般配合條件語句使用,break語句可以改程式的控制流
for( int i = 1 ; i <= 100 ; i++ ){
System.out.println ("請輸入一個數");
int num = sc.nextInt();
if( num == -1 ){
break;
}
}
System.out.println ("輸出1-10之間的不是3的倍數的數");
//continue是結束包含它的當次迴圈,繼續下一次。如果用break,就會只打印出1.2。
for(int i = 1 ; i <= 10 ; i++){
if( i % 3 == 0){
continue;
}
System.out.print ( i +" " );
}
}
3.4.1break
在任何迴圈語句的主體部分,均可用break控制迴圈的流程。break用於強行退出迴圈,不執行迴圈中剩餘的語句。(break語句還可用於多隻語句switch中)
3.4.2continue
continue語句用在迴圈語句體重,用於種植某次迴圈過程,即跳過迴圈體中尚未執行的語句,接著進行下一次是否執行迴圈的判定。
3.4.3return
return語句從當前方法退出,返回到呼叫該方法的語句處,並從該語句的下調語句處繼續執行程式。返回語句的兩種格式:return expression返回一個值給呼叫該方法的語句,返回值的資料型別必須和方法宣告中的返回值型別一致或是精度低於宣告的資料型別。return當方法宣告中用void宣告返回型別為空時,應使用這種返回型別,它不返回任何值。
四、方法
6.1什麼是方法
封裝在一起來執行操作語句的集合,用來完成某個功能操作,在某些語言中稱為函式或者過程,特殊的方法main,程式執行的入口。不可能所有的功能都放到main中,需要定義其他方法完成指定功能,需要時呼叫方法即可。
6.2定義方法
[訪問許可權] [其他修飾符] 返回值型別 <方法名> ([形參列表]){ 方法體 return 返回值; } |
[]是可有可無的 <>是必須要有的。方法內不能在寫方法,方法是同級別的。形參-就是形式引數-類似於數學中的未知數。
上面案列是有返回值型別的。(求2數和的方法),z的返回值型別必須能與方法的型別匹配,如果z是int型,getSum是float型也是可以的,因為能自動轉換。
6.3方法呼叫
int a = 10 ;
int b = 3 ;
//有返回值型別呼叫
int c = Bbreak.getSum(a,b);
System.out.print(c);
//無返回值型別呼叫
Welcome(name);
方法名其實就是方法在記憶體中的地址。方法呼叫的本質就是,通過名字找到方法地址,然後將實參賦給形參。形參的名可以和實參相同,因為作用域不同。
總結步驟:先寫出方法,再在main方法中呼叫方法,將實參賦值給形參,實參在方法中運算出結果,方法返回值就是結果,再將返回值賦值給main方法中的變數,並列印。
方法裡面可以呼叫方法,這是方法的巢狀使用。方法內不能定義方法。
實現兩個整數的交換其實就是值傳遞,傳副本,引用傳遞,傳本身。
堆記憶體中,只有沒有指標指向時,分配的記憶體空間就會死亡,在方法中一樣,方法一用完,即裡面的記憶體空間死亡。
寫方法時一定要功能單一,一個方法只做一件事情。
6.3.1案列:使用者隨意輸入一個數,判斷是否是水仙花數。
public class NarNum {
public static void main(String[] args) {
System.out.println("請輸入一個數:");
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
if(NarNum.isFlawer(num)){
System.out.println("Yes");
}else{
System.out.println("No");
}
}
//判斷是否是水仙花數
private static boolean isFlawer(int num) {
if( num == getSum(num) ){
return true;
}else{
return false;
}
}
//得到輸入的num的和
private static int getSum(int num) {
int sum = 0;
int byt = 0;
int count = getCount(num);
for(int i = 0 ; i < count ; i++ ){
//每次迴圈temp都能取到num的最後一個數 再放入pow()裡面求次冪。
byt = num % 10;
//sum=每次新的餘數次冪加上一次的餘數次冪 153 0+1^3=1 1+5^3=126 126+3^3=153
sum = sum + pow(byt,count);
//每次num/10 如果num=153 那麼num會依次得到15 3 0 ;
num = num / 10;
}
return sum;
}
//計算輸入的num是幾位數
private static int getCount(int num) {
int count = 1;
while( num >= 10 ){
num = num / 10;
count++ ;
}
return count;
}
//計算num的數字次冪
private static int pow(int byt, int count) {
int temp = byt;
for(int i = 1 ; i < count ; i++){
byt = byt * temp ;
}
return byt;
}
}
6.4方法過載
一個類中可以定義有相同的名字,單引數不同的多個方法,呼叫時,會根據不同的引數表選擇對應的方法。
方法過載三大原則:方法名相同,同一作用域,引數不同(資料不同,引數數量不同,引數順序不同,都是引數不同)。方法過載跟方法的返回值型別沒有任何關係。引數的順序不同看資料型別而不是變數名。請勿將功能完全不一樣的方法過載。過載也可能不是萬能的。Println就是每天都在用的過載。
兩個不同的物件,屬性不同,但方法相同,屬性屬於物件的,方法是屬於類的。下面是大概的記憶體圖。
6.5遞迴演算法
程式呼叫自身的程式設計技巧稱為遞迴。一個過程或函式在其定義或說明中有直接或間接呼叫自身的一種方法。
遞迴問題的特點:一個問題可被分解為若干層簡單的子問題,子問題和其上層問題的解決方案一致,外層問題的解決依賴於子問題的解決。遞迴的有點:簡單的程式,缺點:但是遞迴呼叫會佔用大量的系統堆疊,記憶體耗用多,在遞迴呼叫層次多時速度要比迴圈慢的多。
遞迴的使用場合:任何可用遞迴解決的問題也能使用迭代解決。當遞迴方法可以更加自然地反映問題,並且易於理解和除錯,並且不強調效率問題時,可以採用遞迴。在要求高效能的情況下儘量避免使用遞迴,遞迴即花時間又耗記憶體。
//階乘
public class Work07{
public static void main(String [] args){
System.out.println("請輸入0-10的一個整數");
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int res = getNum(num);
System.out.println(res);
}
public static int getNum(int num){
if(num==1){
return 1;
}else{
return num*getNum(num-1);
}
}
}