賦值
上節我們說了數據類型和變量,通過聲明變量,每個變量賦予一個數據類型和一個有意義的名字,我們就告訴了計算機我們要操作的數據。
有了數據,我們能做很多操作。但本文只說說對數據做的第一個操作:賦值。聲明變量之後,就在內存分配了一塊位置,但這個位置的內容是未知的,賦值就是把這塊位置的內容設為一個確定的值。
Java中基本類型、數組、對象的賦值有明顯不同,本文介紹基本類型和數組的賦值,關於對象後續文章會詳述。
我們先來說基本類型的賦值,然後再說數組的賦值。
基本類型的賦值
整數類型
整數類型有byte, short, int和long,分別占用1/2/4/8個字節,取值范圍分別是:
類型名 取值范圍 byte -2^7 ~ 2^7-1 short -2^15 ~ 2^15-1 int -2^31 ~ 2^31-1 long -2^63 ~ 2^63-1我們用^表示指數,2^7即2的7次方。這個范圍我們不需要記的那麼清楚,有個大概范圍認識就可以了,大多數日常應用,一般用int就可以了。後續文章會從二進制的角度進一步分析表示范圍為什麼會是這樣的。
賦值形式很簡單,直接把熟悉的數字常量形式賦值給變量即可,對應的內存空間的值就從未知變成了確定的常量。但常量不能超過對應類型的表示范圍。例如:
byte b = 23; short s = 3333; int i = 9999; long l = 32323;
但是,在給long類型賦值時,如果常量超過了int的表示范圍,需要在常量後面加大寫或小寫的L,即L或l,例如:
long a = 3232343433L;
這個是由於數字常量默認為是int類型。
小數類型
小數類型有float和double,占用的內存空間分別是4和8個字節,有不同的取值范圍和精度,double表示的范圍更大,精度更高,具體來說:
類型名 取值范圍 float1.4E-45 ~ 3.4E+38
-3.4E+38 ~-1.4E-45
double4.9E-324 ~1.7E+308
-1.7E+308 ~ -4.9E-324
取值范圍看上去很奇怪,一般我們也不需要記住,有個大概印象就可以了。E表示以10為底的指數,E後面的+號和-號代表正指數和負指數,例如:1.4E-45表示1.4乘以10的-45次方。後續文章會進一步分析小數的二進制表示。
對於double,直接把熟悉的小數表示賦值給變量即可,例如:
double d = 333.33;
但對於float,需要在數字後面加大寫F或小寫f,例如:
float f = 333.33f;
這個是由於小數常量默認為是double類型。
除了小數,也可以把整數直接賦值給float或double,例如:
float f = 33; double d = 3333333333333L;
boolean類型
這個很簡單,直接使用true或false賦值,分別表示真和假,例如:
boolean b = true; b = false;
字符類型
字符類型char用於表示一個字符,這個字符可以是中文字符,也可以是英文字符。在內存中,Java用兩個字節表示一個字符。賦值時把常量字符用單引號括起來,不要使用雙引號,例如:
char c = 'A'; char z = '中';
關於字符類型有一些細節,後續文章會進一步深度解析。
一些說明
上面介紹的賦值都是直接給變量設置一個常量值。但也可以把變量賦給變量,例如:
int a = 100; int b = a;
變量可以進行各種運算(後續文章講解),也可以將變量的運算結果賦給變量,例如:
int a = 1; int b = 2; int c = 2*a+b; //2乘以a的值再加上b的值賦給c
上面介紹的賦值都是在聲明變量的時候就進行了賦值,但這不是必須的,可以先聲明變量,隨後再進行賦值。
數組類型
賦值語法
基本類型的數組有三種賦值形式,如下所示:
1. int[] arr = {1,2,3}; 2. int[] arr = new int[]{1,2,3}; 3. int[] arr = new int[3]; arr[0]=1; arr[1]=2; arr[2]=3;
第一種和第二種都是預先知道數組的內容,而第三種是先分配長度,然後再給每個元素賦值。
第三種形式中,即使沒有給每個元素賦值,每個元素也都有一個默認值,這個默認值跟數組類型有關。數值類型的值為0,boolean為false, char為空字符。
數組長度可以動態確定,如下所示:
int length = ... ;//根據一些條件動態計算 int arr = new int[length];
雖然可以動態確定,但定了之後就不可以變,數組有一個length屬性,但只能讀,不能改。
一個小細節,不能在給定初始值的同時還給定長度,即如下格式是不允許的:
int[] arr = new int[3]{1,2,3}
這是可以理解的,因為初始值已經決定了長度,再給個長度,如果還不一致,計算機將無所適從。
數組和基本類型的區別
一個基本類型變量,內存中只會有一塊對應的內存空間。但數組有兩塊,一塊用於存儲數組內容本身,另一塊用於存儲內容的位置。
用一個例子來說明,有一個int變量a,和一個int數組變量arr,其代碼,變量對應的內存地址和內存內容如下所示:
代碼 內存地址 內存數據 int a = 100; 1000 100 int arr = {1,2,3}; 2000 3000 3000 1 3004 2 3008 3基本類型a的內存地址是1000,這個位置存儲的就是它的值100。
數組類型arr的內存地址是2000,這個位置存儲的值是一個位置3000,3000開始的位置存儲的才是實際的數據1,2,3。
為什麼數組要用兩塊空間
不能只用一塊空間嗎?我們來看下面這個代碼:
int[] arrA = {1,2,3}; int[] arrB = {4,5,6,7}; arrA = arrB;
這個代碼中,arrA初始的長度是3,arrB的長度是4,後來將arrB的值賦給了arrA。如果arrA對應的內存空間是直接存儲的數組內容,那麼它將沒有足夠的空間去容納arrB的所有元素。
用兩塊空間存儲,這個就簡單的多,arrA存儲的值就變成了和arrB的一樣,存儲的都是數組內容{4,5,6,7}的地址,此後訪問arrA就和arrB是一樣的了,而arrA {1,2,3}的內存空間由於無人引用會被垃圾回收,如下所示:
arrA {1,2,3}
\
\
arrB -> {4,5,6,7}
由上,也可以看出,給數組變量賦值和給數組中元素賦值是兩回事。給數組中元素賦值是改變數組內容,而給數組變量賦值則會讓變量指向一個不同的位置。
上面我們說數組的長度是不可以變的,不可變指的是數組的內容空間,一經分配,長度就不能再變了,但是可以改變數組變量的值,讓它指向一個長度不同的空間,就像上例中arrA後來指向了arrB一樣。
小結
給變量賦值就是將變量對應的內存空間設置為一個明確的值,有了值之後,變量可以被加載到CPU,CPU可以對這些值進行各種運算,運算後的結果又可以被賦值給變量,保存到內存中。
數據可以進行哪些運算?如何進行運算呢?
------------------
未完待續,查看最新文章,敬請關注微信公眾號“老馬說編程”,深入淺出,探索Java編程及計算機技術的本質。原創文章,保留所有版權。