Java編程的邏輯 (2) - 賦值


本系列文章經補充和完善,已修訂整理成書《Java編程的邏輯》,由機械工業出版社華章分社出版,於2018年1月上市熱銷,讀者好評如潮!各大網店和書店有售,歡迎購買,京東自營鏈接http://item.jd.com/12299018.html


賦值

上節我們說了數據類型和變量,通過聲明變量,每個變量賦予一個數據類型和一個有意義的名字,我們就告訴了計算機我們要操作的數據。

有了數據,我們能做很多操作。但本文只說說對數據做的第一個操作:賦值。聲明變量之后,就在內存分配了一塊位置,但這個位置的內容是未知的,賦值就是把這塊位置的內容設為一個確定的值。

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表示的范圍更大,精度更高,具體來說:

類型名 取值范圍
float

1.4E-45 ~ 3.4E+38

-3.4E+38 ~-1.4E-45

double

4.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編程及計算機技術的本質。原創文章,保留所有版權。

-----------

更多相關原創文章

計算機程序的思維邏輯 (1) - 數據和變量

計算機程序的思維邏輯 (3) - 基本運算

計算機程序的思維邏輯 (4) - 整數的二進制表示與位運算

計算機程序的思維邏輯 (5) - 小數計算為什么會出錯?

計算機程序的思維邏輯 (6) - 如何從亂碼中恢復 (上)?

計算機程序的思維邏輯 (7) - 如何從亂碼中恢復 (下)?

計算機程序的思維邏輯 (8) - char的真正含義

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM