1. 程式人生 > 其它 >char型別的實參與char*型別的形參不相容_Java字元編碼和型別轉換

char型別的實參與char*型別的形參不相容_Java字元編碼和型別轉換

技術標籤:char型別的實參與char*型別的形參不相容

一、認識各種編碼方式

ASCII 碼

ASCII碼:上個世紀60年代,美國製定了一套字元編碼,對英語字元與二進位制位之間的關係,做了統一規定。這被稱為ASCII碼,英文名為America Standard Code for Information Interchange 即美國資訊交換標準碼錶。ASCII碼一共規定了128個字元的編碼,比如空格“SPACE”是32(二進位制00100000),大寫的字母A是65(二進位制01000001)。這128個符號(包括32個不能打印出來的控制符號),只佔用了一個位元組的後面7位,最前面的1位統一規定為0。

缺點:

  • 不能表示所有字元。

  • 相同的編碼表示的字元不一樣:比如,130在法語編碼中代表了é,在希伯來語編碼中卻代表(ג) 了字母Gimel

    0285f8aed6504ade0b75ae33705f4e20.png

Unicode 編碼

Unicode碼錶:萬國碼,也是數字和符號的對照關係,開頭0-127部分和ASCII完全一樣,但是從128開始包含有更多的字元,將世界上所有的符號都納入其中。每一個符號都給予一個獨一無二的編碼,使用 Unicode 沒有亂碼的問題。(java語言預設使用的編碼表)

缺點:Unicode 只規定了符號的二進位制程式碼,卻沒有規定這個二進位制程式碼應該如何儲存:無法區別 Unicode 和 ASCII:計算機無法區分三個位元組表示一個符號還是分別表示三個符號。另外,我們知道,英文字母只用一個位元組表示就夠了,如果unicode統一規定,每個符號用三個或四個位元組表示,那麼每個英文字母前都必然有二到三個位元組是0,這對於儲存空間來說是極大的浪費。

805af417bd27d7075adfade88fe5af17.png

UTF-8

UTF-8 是一種變長的編碼方式。它可以使用 1-6 個位元組表示一個符號,根據不同的符號而變化位元組長度。UTF-8 是在網際網路上使用最廣的一種 Unicode 的實現方式。

UTF-8的編碼規則:

對於單位元組的UTF-8編碼,該位元組的最高位為0,其餘7位用來對字元進行編碼(等同於ASCII碼)。

對於多位元組的UTF-8編碼,如果編碼包含 n 個位元組,那麼第一個位元組的前 n 位為1,第一個位元組的第 n+1 位為0,該位元組的剩餘各位用來對字元進行編碼。在第一個位元組之後的所有的位元組,都是最高兩位為"10",其餘6位用來對字元進行編碼。

48bdc5846e8f3060a3ac2bbd9607ab4b.png

亂碼:世界上存在著多種編碼方式,同一個二進位制數字可以被解釋成不同的符號。因此,要想開啟一個文字檔案,就必須知道它的編碼方式,否則用錯誤的編碼方式解讀,就會出現亂碼。

二、基本資料型別轉換

自動型別提升(隱式)

特點:程式碼不需要進行特殊處理,自動完成。

容量小的型別自動轉換為容量大的資料型別。資料型別按容量大小(容量大小指的是數表示的範圍,並非佔用記憶體空間的大小)排序為:

57a664f84c7291876c44ce4a15e1a69c.png

有多種型別的資料混合運算時,系統首先自動將所有資料轉換成容量最大的那種資料型別,然後再進行計算。

byte,short,char之間不會相互轉換,他們三者在計算時首先轉換為int型別。

boolean型別不能與其它資料型別運算。

自動型別提升的特殊情況:

在給變數進行賦值的時候,如果右側的表示式當中全都是常量,沒有任何變數,那麼編譯器javac將會直接將若干個常量表達式計算得到結果。

例如:short result=5+8;

等號右邊全都是常量,沒有任何變數參與運算編譯之後,得到的.class位元組碼檔案當中相當於【直接就是】:

short result=13;

右側的常量結果數值,沒有超過左側範圍,所以正確。這稱為“編譯器的常量優化”。但是注意:一旦表示式當中有變數參與,那麼就不能進行這種優化了。

//情況一:byte b1 =1;byte b2 =2;byte b3=b1+b2;System.out.println(b3);//編譯報錯 錯誤:不相容的型別 可能會溢位(計算機在解釋執行時才會在記憶體中開闢空間,但編譯的時候計算機不知道這個變數的值)

注:(情況一中的byte、short、char替換為int或者long則不會報錯,因為本身範圍大,相當於java給的特權)

//情況二:byte b1 =1;byte b2 =b1+2;System.out.println(b2);//編譯報錯 錯誤:不相容的型別 可能會溢位(計算機在解釋執行時才會在記憶體中開闢空間,但編譯的時候計算機不知道這個變數的值

即假設b1的值是127這種臨界值,還是不會超,但是一相加的值就不確定就可能溢位。即右邊是常量就可以做自動轉換,右邊如果是變數就不做自動轉換,因為做了自動轉換就可能帶來精度的丟失。)

byte b1=2;b1+=5;System.out.println(b1);

編譯正確,複合賦值運算子其中隱含了一個強制型別轉換。+=是java語言規定的運算子,java編譯器會對它進行特殊處理,因此可以正確編譯。

d385b216d66620ad8c470dec5720ae96.png

•特例

對於byte/short/char三種類型來說,如果右側賦值的數值沒有超過範圍,那麼javac編譯器將會自動隱含地為我們補上一個(byte)(short)(char)。

1.如果沒有超過左側的範圍,編譯器補上強轉。

2.如果右側超過了左側範圍,那麼直接編譯器報錯。

• 可以將整型常量直接賦值給byte, short, char等型別變數,而不需要進行強制型別轉換,只要不超出其表數範圍

//情況三:byte b =126+1;System.out.println(b);//編譯正確
//情況四:byte b = 127+1;System.out.println(b);//編譯報錯 超出byte的範圍

0d144c67b033832f46c717f748cfe801.png

強制型別轉換(顯式轉換)

特點:程式碼需要進行特殊的格式處理,不能自動完成。

格式:範圍小的型別 範圍小的變數名=(範圍小的型別)原本範圍大的資料

注:強制型別轉換時右邊轉換型別必須用小括號括起來

boolean型別不可以轉換為其它的資料型別。

自動型別轉換的逆過程,將容量大的資料型別轉換為容量小的資料型別。使用時要加上強制轉換符:(),但可能造成精度降低或溢位,格外要注意。

通常,字串不能直接轉換為基本型別,但通過基本型別對應的包裝類則可以實現把字串轉換成基本型別。

Stringa=“43”;inti=Integer.parseInt(a);

精度損失舉例

inti2=128;byte b = (byte)i2;System.out.println(b);//-128

字串型別:String

String不是基本資料型別,屬於引用資料型別

使用方式與基本資料型別一致。例如:String str = “abcd”;

一個字串可以串接另一個字串,也可以直接串接其他型別的資料。當把任何基本資料型別(包括布林型)的值和字串(String)進行連線運算且只能是連線運算時(+),基本資料型別的值將自動轉化為字串(String)型別。例如:

str = str + “xyz” ;int n = 100;str=str+n;

常見字串和其他資料型別拼接練習舉例:

char c='a';int num=10;String str="hello";System.out.println(c+num+str);//107helloSystem.out.println(c+str+num);//ahello10System.out.println(c+(num+str));//a10helloSystem.out.println(str+num+c);//hello10a

練習:

//輸出:* *System.out.println("* *");//* *System.out.println('*'+'\t'+'*');//93System.out.println('*'+"\t"+'*');//* *System.out.println('*'+'\t'+"*");//51*System.out.println('*'+('\t'+"*"));//* *