實值型別與參考型別分類
預設內建型別
| 分類 | 包含型別 |
|---|---|
| 實值型別(基礎數值 / 布林 / 字元) | 有號整數:sbyte、short、int、long無號整數: byte、ushort、uint、ulong浮點 / 高精密度: float、double、decimal布林: bool字元: char |
| 參考型別(內建參考) | object(所有型別基底類別)、string、dynamic |
使用者自訂型別
| 分類 | 型別 |
|---|---|
| 實值型別 | struct(結構)、enum(列舉) |
| 參考型別 | class、interface、delegate、array(陣列) |
如同上一堂課提到,參考型別的資料一定存放在堆積;但實值型別的資料,有可能放在堆積,也有可能放在堆疊。
參考型別的參考本體,可能存放在堆積,也可能存放在堆疊。
至於要存堆積還是堆疊,取決於這個實值型別變數、或是參考型別的參考,到底是類別的成員,還是函式內區域變數。
四種變數
| 變數類型 | 定義與用途 |
|---|---|
| 區域變數 Local variable | 方法內暫存資料,不屬於類型成員; 存放於堆疊 不會自動初始化 |
| 欄位 Field | 綁定類別/結構的資料,屬於類型成員; 類別欄位存放於堆積 結構欄位跟隨結構存放; 自動初始化 |
| 參數 Parameter | 方法傳入引數的暫時變數,不屬於類型成員; 存放於堆疊 不會自動初始化 |
| 陣列元素 Array element | 陣列內單筆資料; 全部配置在堆積 自動初始化 |
所謂自動初始化,意思是就算程式設計師沒有給變數初始值,編譯器也會自動指派預設值。
簡單整理如下
| 變數類型 | 儲存位置 | 是否自動初始化 |
|---|---|---|
| 區域變數 | 堆疊 / 堆疊 + 堆積 | 否 |
| 類別欄位 | 堆積 | 是 |
| 結構欄位 | 堆疊 / 堆積 | 是 |
| 方法參數 | 堆疊 | 否 |
| 陣列元素 | 堆積 | 是 |

變數宣告
語法格式:型別 變數名;
int var2;Code language: C# (cs)
這行程式碼用來宣告變數,主要完成兩件事情:
- 告知編譯器 var2 是 int 型別的變數,名稱為 var2。
- 編譯器會配置記憶體空間;至於放在堆積還是堆疊,要看情境:此變數是區域變數、參數或是欄位等等。

變數初始設定器(Initializer)
語法:型別 變數名 = 初始值;
範例:int var2 = 17;
初始設定器是編譯器提供的機制,協助我們初始化變數。部分變數一定要由開發者手動初始化,另外一部分變數可以交由初始設定器自動處理。
未初始化的區域變數數值未定義,會觸發編譯錯誤,無法直接使用;
欄位、陣列元素等支援自動初始化的變數會被指派預設值:數值型別預設為0,參考型別預設為null。
請參考範例:
class Program
{
static void Main(string[] args)
{
int times = 100;
Person person = new Person();
}
}
class Person
{
public int age;
}
Code language: C# (cs)
這個範例很簡單,Main 函式內宣告了實值型別變數 times,以及參考型別變數 person,參考型別裡包含欄位 age。
age 沒有指定初始值,times 則由我們手動給予初始值。
此段程式可以正常編譯。

如果把 times 移除初始值 100,改寫如下

變數下方會直接出現紅色波浪線,無法通過編譯。
強行編譯就會彈出錯誤訊息

錯誤清單視窗會列出詳細錯誤

注意:必須在程式裡使用 times 變數才會報錯;如果完全沒有存取,就不會觸發錯誤,依舊能夠編譯。
class Program
{
static void Main(string[] args)
{
int times;
Person person = new Person();
}
}
Code language: C# (cs)
但如果是類別內的欄位,像是下方 Person 的 age,就算沒有手動初始化,程式依舊可以編譯執行。
class Program
{
static void Main(string[] args)
{
int times = 100;
Console.WriteLine(times);
Person person = new Person();
Console.WriteLine(person.age);
}
}
class Person
{
public int age;
}
Code language: C# (cs)

執行後可以看到輸出 0。age 做為類別成員欄位,未手動初始化時,初始設定器會自動指派預設值;int 的預設值是0,不同型別各自有不同預設值。
同一行宣告多個變數
- 同一行只能宣告相同型別的變數;
- 變數名稱以逗號分隔,可以同時存在已初始化與未初始化變數;
- 禁止同一行混合多種資料型別。
// 合法
int var3 = 7, var4, var5 = 3;
double var6, var7 = 6.52;
// 非法!同時混用 int 與 float
int var8, float var9;
Code language: JavaScript (javascript)
讀取變數內容
直接寫上變數名稱,就能讀取記憶體內存放的數值:
Console.WriteLine("{0}", var2);Code language: JavaScript (javascript)

變數