1. 程式人生 > >1.java 基本資料型別、運算子、控制語句、方法和遞迴

1.java 基本資料型別、運算子、控制語句、方法和遞迴

1.基本資料型別

  Java是一種強型別語言,每個變數都必須宣告其資料型別。 Java的資料型別可分為兩大類:基本資料型別(primitive data type)和引用資料型別(reference data type)。

Java中定義了3類8種基本資料型別

(1)整形(byte、short、int、long

   整型用於表示沒有小數部分的數值,它允許是負數。

 

Java 語言整型常量的四種表示形式

  • 十進位制整數,如:99, -500, 0

  • 八進位制整數,要求以 0 開頭,如:015

  • 十六進位制數,要求 0x 或 0X 開頭,如:0x15

  • 二進位制數,要求0b或0B開頭,如:0b01110011

注意:Java語言的整型常數預設為int型,宣告long型常量可以後加‘l’或‘ L ’,一般加‘L’

 

(2)浮點型(float、double

float型別又被稱作單精度型別,尾數可以精確到7位有效數字,double表示這種型別的數值精度約是float型別的兩倍,又被稱作雙精度型別,絕大部分應用程式都採用double型別。浮點型常量預設型別也是double。

Java浮點型別常量有兩種表示形式

  • 十進位制數形式,例如:3.14       314.0      0.314 

  • 科學記數法形式,如314e2      314E2      314E-2

注意:Java語言的浮點型常數預設為double型,宣告float型別的數值有一個字尾F 。

由於精度問題,實際使用時應該儘量避免兩個浮點數進行比較,同時如果需要進行沒有誤差的精確數字進行計算,可以使用java.math包中的BigIntegerBigDecimal類。以BigInteger為例,BigDecimal同理:

import java.math.BigDecimal;
public class Main {
	public static void main(String[] args) {
		BigDecimal bd = BigDecimal.valueOf(1.0);
		bd = bd.subtract(BigDecimal.valueOf(0.1));
		bd = bd.subtract(BigDecimal.valueOf(0.1));
		bd = bd.subtract(BigDecimal.valueOf(0.1));
		bd = bd.subtract(BigDecimal.valueOf(0.1));
		bd = bd.subtract(BigDecimal.valueOf(0.1));
		System.out.println(bd);//0.5
		System.out.println(1.0 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1);//0.5000000000000001
	}
}

(3)字元型(char)

字元型在記憶體中佔2個位元組,在Java中使用單引號來表示字元常量。

char 型別用來表示在Unicode編碼表中的字元。Unicode具有從0到65535之間的編碼,他們通常用從’\u0000’到’\uFFFF’之間的十六進位制值來表示(字首為u表示Unicode)。

Java 語言中還允許使用轉義字元 ‘\’ 來將其後的字元轉變為其它的含義。常見轉義字元:

(4)布林型(boolean)

boolean型別有兩個常量值,true和false,在記憶體中佔一位(注意:不是一個位元組)。

一般不寫成if(flag == true)而是寫成if(flag)

2.運算子

注意:右移一位除以2(整除),左移一位乘以2。

&和&&的區別:

  1. &和&&都可以用作邏輯與的運算子,表示邏輯與(and),當運算子兩邊的表示式的結果都為true時,整個運算結果才為true,否則,只要有一方為false,則結果為false。

  2. &&還具有短路的功能,即如果第一個表示式為false,則不再計算第二個表示式,例如,對於if(str != null && !str.equals(“”))表示式,當str為null時,後面的表示式不會執行,所以不會出現NullPointerException如果將&&改為&,則會丟擲NullPointerException異常。If(x==33 & ++y>0) y會增長,If(x==33 && ++y>0)不會增長

  3. &還可以用作位運算子,當&操作符兩邊的表示式不是boolean型別時,&表示按位與操作,我們通常使用0x0f來與一個整數進行&運算,來獲取該整數的最低4個bit位,例如,0x31 & 0x0f的結果為0x01

運算子優先順序問題:

1.沒必要知道,需要的時候,使用()表示運算先後順序,使程式可讀性強。

2.邏輯與、邏輯或、邏輯非的優先順序一定要熟悉!(邏輯非>邏輯與>邏輯或)。

  如:a||b&&c的運算結果是:a||(b&&c),而不是(a||b)&&c 

(重點)型別轉化問題:

1.自動型別轉換:

自動轉換按從低到高的順序轉換。不同型別資料間的優先關係如下:
    低--------------------------------------------->高
    byte,short,char-> int -> long -> float -> double

運算中,不同型別的資料先轉化為同一型別,然後進行運算,轉換規則如下:

運算元1型別

運算元2型別

轉換後的型別

byte、short、char

int

int

byte、short、char、int

long

long

byte、short、char、int、long

float

float

byte、short、char、int、long、float

double

double

2.強制型別轉換:

強制轉換的格式是在需要轉型的資料前加上“( )”,然後在括號內加入需要轉化的資料型別。有的資料經過轉型運算後,精度會丟失。

double x  = 3.14; 
int nx = (int)x;   //值為3
char c = 'a';
int d = c+1;

注意:

1.當將一種型別強制轉換成另一種型別,而又超出了目標型別的表數範圍,就會被截斷成為一個完全不同的值。

int x = 300;
byte bx = (byte)x;    //值為44

2.不能在布林型別和任何數值型別之間做強制型別轉換。

3.控制語句

選擇結構(if 和switch)


import java.util.Scanner;

public class TestIf {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("please input your score");
		int x = sc.nextInt();
		if(x<60) {
			System.out.println("D");
		}else if(x<75) {
			System.out.println("C");
		}else if(x<85) {
			System.out.println("B");
		}else {
			System.out.println("A");
		}
	}
}

switch基本不用,懶得寫了


switch (表示式) {
case 值1: 
語句序列1;
[break];
case 值2:
 語句序列2;
[break];
     … … …      … …
[default:
 預設語句;]
}

迴圈結構(while   do-while  for)注意break和continue

for迴圈

//計算0~100的和
public class Demo {
	public static void main(String[] args) {
		int sum = 0;
		for(int i=0;i<=100;i++) {
			sum += i;			
		}
		System.out.println(sum);
	}
}

while迴圈

//計算0~100的和
public class Demo {
	public static void main(String[] args) {
		int i = 0;
		int sum = 0;
		while(i <= 100) {
			sum += i;
			i++;
		}
		System.out.println(sum);
	}
}

do-while

//計算0~100的和
public class Demo {
	public static void main(String[] args) {
		int i = 0;
		int sum = 0;
		do {
			sum += i;
			i++;
		}while(i <= 100);
		System.out.println(sum);
	}
}

4.方法(函式)

方法的過載(overload):

過載的方法,實際是完全不同的方法,只是名稱相同而已!

      構成方法過載的條件:

  1. 不同的含義:形參型別、形參個數、形參順序(首先要型別不同)不同
  2. 只有返回值不同不構成方法的過載
  3. 只有形參的名稱不同,不構成方法的過載
public class Demo {
    public static void main(String[] args) {
        System.out.println(add(3, 5));// 8
        System.out.println(add(3, 5, 10));// 18
        System.out.println(add(3.0, 5));// 8.0
        System.out.println(add(3, 5.0));// 8.0
        // 我們已經見過的方法的過載
        System.out.println();// 0個引數
        System.out.println(1);// 引數是1個int
        System.out.println(3.0);// 引數是1個double
    }
    /** 求和的方法 */
    public static int add(int n1, int n2) {
        int sum = n1 + n2;
        return sum;
    }
    // 方法名相同,引數個數不同,構成過載
    public static int add(int n1, int n2, int n3) {
        int sum = n1 + n2 + n3;
        return sum;
    }
    // 方法名相同,引數型別不同,構成過載
    public static double add(double n1, int n2) {
        double sum = n1 + n2;
        return sum;
    }
    // 方法名相同,引數順序不同,構成過載
    public static double add(int n1, double n2) {
        double sum = n1 + n2;
        return sum;
    }
    //編譯錯誤:只有返回值不同,不構成方法的過載
    public static double add(int n1, int n2) {
        double sum = n1 + n2;
        return sum;
    }
    //編譯錯誤:只有引數名稱不同,不構成方法的過載
    public static int add(int n2, int n1) {
        double sum = n1 + n2;         
        return sum;
    }  
}

遞迴:

遞迴的基本思想就是“自己呼叫自己”,一個使用遞迴技術的方法將會直接或者間接的呼叫自己。

遞迴結構包括兩個部分:

      1.定義遞迴頭:什麼時候不呼叫自身方法,也就是遞迴的結束條件。如果沒有頭,將陷入死迴圈。

      2.遞迴體:什麼時候需要呼叫自身方法。

//計算n的階乘
public class Demo {
	public static void main(String[] args) {
		System.out.println(factorial(10));
	}
	
	public static long factorial(int n) {
		if(n == 1) {//遞迴頭
			return 1;
		}else {
			return n*factorial(n-1);  //遞迴體
		}
	} 
}

  利用遞迴可以用簡單的程式來解決一些複雜的問題。比如:斐波那契數列的計算、漢諾塔、快排等問題。但是遞迴呼叫會佔用大量的系統堆疊,記憶體耗用多,在遞迴呼叫層次多時速度要比迴圈慢的多,所以在使用遞迴時要慎重。