2013年9月3日 星期二

變數

作者: 許裕永
1. 變數的使用
什麼是程式設計?基本的定義是「資料及演算法的結合,處理已知的問題」。簡單的說就是:「運算資料,得到結果」。而在運算的過程中,資料必要時必須暫時或長期的儲存起來,以提供再運算。那麼這些資料儲存在那裡呢?
電腦運算時,能儲存資料的,自然是記憶體空間了。但是記憶體空間是由作業系統管理的,程式設計師如何在程式碼中支配呢?答案就是「變數」。我們在程式中宣 告一個變數,執行時期,Java便會依照此變數的型別,配置一個適當大小的記憶體空間,來讓我們儲存資料。而變數名稱便是該記憶體空間的代號。所以:「變 數是程式設計師用來存取記憶體空間的代號」。
變數依照宣告時的型別,可分為基本變數(primitive variable)及參考變數(reference variable)。以基本資料型別宣 告之變數,就是基本變數。其他不是以基本資料型別(包括類別、界面及陣列)所宣告之變數,即為參考變數,或譯為參照變數。
2. 基本資料型別
為了有效的運用記憶體空間,提升資料運算的效率。Java將資料規劃為8種基本資料型別(primitive type),並分別設定其佔用的記憶體空間大小及資料範圍:

資料種類 型別名稱 記憶體空間 資料範圍
整數 byte 1byte -27~27-1
short 2byte -215~215-1
int 4byte -231~231-1
long 8byte -263~263-1
浮點數 float 4byte 視作業系統而定
doublt 8byte 視作業系統而定
字元 char 2byte 0~216-1
布林值 boolean 1byte true/false
3. 基本變數的宣告及指派
3-1 基本變數宣告:
基本資料型別 變數名稱〔=資料,變數名稱=資料〕;
中括號代表可以省略。
例一:
byte age;
執行時,Java會配置1byte大的記憶體空間給程式,並將該記憶體空間命名為age。但記憶體空間中並未儲存資料,所以目前此變數不得置於運算式中,否則會造成編譯錯誤。
例二:
int height=168;
執行時,Java會配置4byte大的記憶體空間給程式,並將該記憶體空間命名為height。記憶體空間中儲存的資料為整數168。此敍述句稱之為宣告變數並指派初值。
例三:
int year=2006,month=12,day;
相同型別的變數可以在同一行敍述句中宣告並分別指派或不指派初值。
 
3-2 指派:
變數名稱=資料;
變數宣告後,可以隨時指派新資料,以之取代舊資料。
例一:
age=18;
變數名稱在‘=’左側時,代表記憶體空間。所以此敍句的意思是:將資料18儲存於age所代表之記憶體空間中。
例二:
height=age;
變數名稱在‘=’右側時,代表記憶體空間所儲存的資料。所以此敍述句的意思是:複製變數age代表的記憶體空間中所儲存的資料,再把該資料儲存於height所代表的記憶體空間中。而因為是複製,所以變數age所代表的記憶體空間中的資料,不會有任何變化。
例三:
height=8*5;
當‘=’右側是運算式時,代表將運算式的運算結果,儲存於變數height所代表的記憶體空間。
例四:
height=age*5;
先複製變數age所代表的記憶體空間中的資料,來和5做乘的運算。再將運算後的結果,儲存於變數height所代表的記憶體空間。因為是複製,所以變數age所代表的記憶體空間中的資料,不會有任何變化。
例五:
height=height*5;
先複製變數height所代表的記憶體空間中的資料,來和5做乘的運算。再將運算後的結果,儲存於變數height所代表的記憶體空間。此時新資料將取代舊資料。
3-3 變數命名:
變數名稱允許使用大、小寫的英文字母、數字、底線符號(_)及貨幣符號($)來組合,但不可以用數字開頭。(雖然可以使用中文為變數名稱,但顧及日後身為高級程式設計師的你,可能在非中文作業系統中開發和修改程式碼,所以不建議使用。)
例:
int a;
int _a;
int $a;
int a_0$5bcd;
int aAbB;
int AaBb;
以上均為合法之變數名稱。最後兩個變數視為不同之變數名稱。
int 0a; //數字開頭
int a*; //使用了不允許的符號
int a b; //使用了空格
以上均為不合法之變數名稱
3-4 資料樣式:
變數資料的指派,Java會把等號右側的值讀入後,先儲存在運算用的記憶體空間,後然再把值複製到程式碼指定的變數空間。
整數值的預設型別為int。也就是說:Java在程式碼中,讀到整數數值時,會先取得4byte的運算用記憶體空間來暫時儲存,然後再把值複製到指定的變 數所代表的記憶體空間中儲存。若程式碼中的數值未超過int的最大或最小值的範圍(4個byte),自然沒有問題。但若程式碼中的數值超過int的最大或 最小值範圍,則將產生溢位的錯誤。
整數型別中,大於int範圍的只有long,所以只須注意long變數的指派即可。也就是說:要指派給long型別變數的值,大於int最大或最小值時, 必須在數值尾端加上大寫‘L’或小寫的‘l’(建議用大寫)。這樣Java將會取得8byte的運算用記憶體空間,來儲存此數值,才不會產生溢位的錯誤。
例:
byte a=8; //正確,數值未超過int範圍
short b=80; //正確,數值未超過int範圍
int c=800; //正確,數值未超過int範圍
long a=2147483647; //正確,未超過int最大值
long b=2147483648; //錯誤,已超過int最大值
long c=2147483648L; //正確,數值尾端加上‘L’
整數資料在程式碼中除了用10進位表示外,也可以用8進位或16進位來表示。不過8進位及16進位的演算並不在SCJP 5‧0的認證範圍中,所以只要知道其表示方式就可以了。
例:
int a=38; //10進位
int b=046; //0開頭,代表8進位,此值為10進位之38
int c=0x26; //0x開頭,代表16進位,此值為10進位之38
浮點數的預設型別為double,也就是說:Java在程式碼中讀到浮點數數值時,會預設取得8byte的運算用記憶體空間來暫時儲存,然後再把值複製到 指定變數所代表的記憶體空間中儲存。若配置給變數的記憶體空間是8byte自然沒問題,但若小於8byte則會產生型別不符的錯誤。
而浮點數型別中,小於8byte的只有float,所以只須注意float變數的指派即可。也就是當程式碼中的數值是要指派給float變數時,無論值之 大小,均須於數值尾端加上大寫‘F’或小寫的‘f’(建議用大寫)。這樣Java只會取得4byte的運算用記憶體空間,來儲存此數值,指派給float 變數時,便不會產生型別不符的錯誤。
例:
double a=3.0D;//正確,數值尾端加‘D’表示此數值為double
double b=3.0; //正確,數值尾端未加‘D’,亦預設為double
float a=3; //正確,數值3是整數,預設型別為int(4byte)
float b=3.0; //錯誤,數值3‧0是浮點數,預設型別為double
float c=3.0F; //正確,浮點數尾端加上F
字元資料的基本樣式是以單引號括住的單一字母,數字或符號。
例:
char a=’a’;
char =’8’;
char c=’;’;
也可以在單引號中用\u開頭加上以16進位表示之字元碼。
例:
char a=’\u004E’; //此為字元‘N’的16進位字元碼
但其實電腦在運算字元資料時,是在運算字元碼(Unicode),所以指派時也可以直接用字元碼(整數樣式)指派。而因為字元型態配置2byte的記憶體空間,所以其整數值的範圍為0~65535。
例:
char a=38;
char b=046;
char c=0x26;
布林值的表示方式只有兩個變化,true或false。true代表成立,false代表不成立,此值運用在條件運算式。特別要注意的是,布林值無法與其他值替換,不像在某些程式語言中1可以代表true,0可以代表false。
3-5 變數的存活範圍:
變數只存活在變數宣告的程式區塊中。程式區塊指的是大括號,當日後程式碼較為複雜時,請注意內圍區塊可以存取外圍區塊已宣告的變數,但外圍區塊不可以存取內圍區塊所宣告的變數。
例:
public static void main(String[] args){
 int a=8;
 if(a>5){
  int b=a*10;//if區塊可以存取main區塊所宣告之變數a
 }
 System.out.println(b);
}
執行結果:編譯錯誤,因為b只存活在if的區塊中。
撰寫程式碼時,可以任意用大括號來建立程式碼區塊,此時便需注意變數的存活範圍。
例:
public static void main(String[] args){
 int a=8;
 {
  int b=a*10;
  System.out.println(b);
 }
 System.out.println(a);
}
列印結果:80 8。
4. 參考變數的宣告及指派

※ 本節內容,後續章節才有詳細解說,讀者此時只宜略讀,稍有概念即可。有不了解處,可於熟讀後續章節(第五章)後,再回來研讀。
4-1 參考變數宣告:
參考變數宣告後,同基本變數一樣。在執行時期,Java均會配置適當的記憶體空間,並以變數名稱為代號。不同之處有:一、基本變數所配置的記憶體空間大 小,會依照型別的規格配置;但參考變數一律配置2byte。二、基本變數所代表的記憶體空間中所儲存的是資料(值),但參考變數所代表的記憶體空間中所儲 存的,是一個物件(一整塊連續的記憶體空間)的代號(由Java所產生)。
類別名稱 變數名稱〔= new 建構方法()〕;
界面名稱 變數名稱〔= new 有實做界面的類別的建構方法()〕;
陣列資料型別〔〕 變數名稱〔= new 陣列資料型別〔陣列長度〕〕;
例一:
String s=new String(“Java”);
String是一個類別名稱,意思是字串。new是一個指令,意思是配置一塊連續的記憶體空間來儲存“Java”的值,並產生一個物件代號。再將代號儲存於參考變數s所代表的記憶體空間。
用new這個指令來配置一塊連續的記憶體空間,在專門名詞中稱之為「建構物件」(create instance)。而這個記憶體區塊的代號,本書便稱之為物件代號。
其實,程式中再怎麼複雜的資料,一定都是基本資料型別的資料組成的。而因為是一群資料,所以必須用一個代號來代表它們,並將此代號儲存於變數中,讓程式設 計師可以利用這個變數所儲存的代號,來參照到這一群資料。這個變數可以讓我們參考它的代號而存取一堆資料,所以稱之為「參考變數」(reference  variable),而這一群資料,我們稱之為「物件」(Object)。
物件的型別就是宣告句最前面的類別名稱(界面名稱、陣列型別)。這個範例中,我們可以稱呼這個物件為String物件。而在程式中,參考變數s可以代表這 個物件,所以我們也可以說:s是這個String物件的物件名稱。但,在這裡我們必須特別留意的是:物件名稱不是物件。物件名稱(參考變數)只是代表某一 個物件,所謂的物件指的是儲存那一群資料的連續記憶體區塊。
例二:
int[] a=new int[5];
new int〔5〕,是要求配置5個int大小的記憶體空間,這一連續記憶體區塊可以稱之為int陣列物件,這個物件的名字叫做a。
5. 基本資料型態轉換
程式設計就是資料的運算,而不同的資料型別有不同的運算方式。當一個運算式中參雜著不同型別的資料時,Java會先試著將運算符號前後的資料,自動轉換成同一型別後再運算。但若自動轉換失敗,便會產生錯誤。
5-1 自動轉換:
1. 整數自動由小轉大。(依配罝之記憶體空間)
2. 整數自動轉浮點數。(long亦可自動轉換為float)
3. 字元可自動轉成整數或浮點數。
4. 布林值無法自動轉換為任何基本資料型別。
5. 所有基本資料型別的資料均可自動轉為字串資料(“……”)。
例:
byte a=18;
short b=a;
int c=b;
long d=c;
float e=d;
double f=e;
System.out.println(“我今年”+ f + “歲,是” + true);
列印結果:我今年18歲是true。
5-2 強制轉換:
在值的前方加上“(資料型別)”,便會強制轉換,但若是由大轉小,有可能造成資料流失。
例:
int a=25;
byte b=(byte)a;
System.out.println(b);
//因為25未超過byte之範圍,所以值未受影響
a=256;
b=(byte)a;
System.out.println(b);
//因為256已超過byte之範圍,所以值受影響,會列印0
型別轉換時,不可以被值給迷惑了。以上例而言,當a之值為25時,要把a的值指派給變數b,明明25還在b的範圍之內,為什麼還要強制轉換?為什麼不會自 動轉換?請注意,對Java而言,我們是要把變數a的值,儲存進變數b;而不是把25儲存進變數b。也就是說:我們是要把最大可以4byte大的東西,置 入1byte大的容器。自然需要用指令來強制轉換。而如果要轉換的值超過1byte大的時候,還需要動手術才能放得下,所以它的值就會產生變化。(變化的 方式為補數,不在認證範圍)
6. 常數的宣告及指派
常數宣告後,只能指派一次。宣告時在資料型別的前面加上修飾字final。
final  資料型別 常數名稱〔=資料〕;
例:
final int a;
final int b=10;
final String s;
final String t=new String(“Java”);
a=8;
s=new String(“SCJP”);
//常數b為合法的宣告並指派
//常數as為宣告後再指派,但只能指派一次
7. 認證重點整理
  • 變數名稱允許使用大小寫的英文字母,數字,底線符號(_)及貨幣符號($)來組合,但不可以用數字開頭。
  • 整數的預設型別為int,浮點數的預設型別為double。
  • 整數值若大於int之最大或最小範圍,必須在值的尾端加上‘L’或‘l’。
  • 浮點數的值若要指派給float型別的變數,必須在值的尾端加上‘F’或‘f’。
  • 字元資料總共有5種表示方式。
  • 布林值的true跟false,不能用數字的1跟0替換。
  • 變數只存活宣告的程式區塊中。
  • 參考變數所代表的記憶體空間裏,儲存的不是資料,而是儲存一群資料的連續記憶體區塊的代號。
  • 物件是指用new配置的連續記憶體區塊,區塊中儲存著資料。
  • 參考變數也可以稱之為物件名稱;參考變數可以參照到物件,也可以說參考變數代表物件,但參考變數(物件名稱)不是物件。
  • long型別的資料可以自動轉換為float的型別。
  • 常數宣告時不一定要立刻指派,但只能指派一次

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。