第 2 課 · 約 12 分鐘 · ← 第 1 課

變數與核心型別

每個 C# 值都有一個型別,在你寫下的那一刻就定了。認識你每天都要用的五個,以及每個新手都會中一次的三記陷阱。

變數是貼了標籤的盒子,形狀只有一種

宣告變數 = 預定一個盒子、貼上標籤、決定什麼形狀能放進去。一旦決定,形狀永不改變:

int age = 36;              // 只裝整數
double height = 1.7;       // 小數
string name = "Ada Lovelace"; // 文本,帶引號
bool isProgrammer = true;  // 只有 true 或 false

Console.WriteLine(age);
Console.WriteLine(name);
Console.WriteLine(isProgrammer);

把 int age = 36; 從右往左讀:"造出 36,放進一個叫 age、只裝 int 的盒子。"型別是承諾——對編譯器,也對未來的每個讀者。

以後會常遇到的 char

第五個核心型別裝單個字元,用單引號。它和一位元組的字串是不同物種:

char letter = 'a';        // 單引號 = 恰好一個字元
Console.WriteLine(letter);
Console.WriteLine(letter + 0);     // 意外:char 就是它的數字(97 = 'a' 的碼)
Console.WriteLine((char)(letter + 1));  // ……所以 char 能做運算

var:同樣的盒子,讓編譯器替你貼標籤

var 不是"隨便什麼型別都行"——它意思是"編譯器,看看右邊,替我把型別填上":

var price = 9.99;   // 編譯器寫成:double price = 9.99;
var count = 42;     // 編譯器寫成:int count = 42;

Console.WriteLine(price);
Console.WriteLine(count);

證明它不是動態型別——去練習場往一個 var 數字裡塞文本:編譯器拒絕的方式和你寫 int 時一模一樣。(完整故事:var 與顯式型別。)

陷阱一:int 除法扔掉小數

Console.WriteLine(7 / 2);    // 兩邊 int → 整數運算 → 3
Console.WriteLine(7 / 2.0);  // 一邊 double → double 運算 → 3.5

它有一篇專門的文章:為什麼 C# 裡 7 / 2 = 3——包括負數規則和三種修法。

陷阱二:int 有天花板——而且會迴繞

int biggest = int.MaxValue;
Console.WriteLine(biggest);
Console.WriteLine(biggest + 1);   // 迴繞成最負的 int!

int 是 32 位:裝得下 −2,147,483,648 … 2,147,483,647。過了天花板就回繞(像汽車裡程表)。更大的整數,真實程式碼用 long(64 位)。

陷阱三:double 是近似值

Console.WriteLine(0.1 + 0.2 == 0.3);             // False!和是 0.30000000000000004…
Console.WriteLine((0.1 + 0.2).ToString("F2"));  // 0.30 —— 顯示格式把它藏起來了

double 用二進位制存小數,而某些十進位制值(0.1!)沒有精確的二進位制形式——就像 ⅓ 沒有精確的十進位制形式。顯示用 F2 這類格式;永遠別用 == 比較 double;錢用 decimal。

列印:把值拼進文本

三種寫法,同一結果。插值是現代首選:

string name = "Ada";
int age = 36;

Console.WriteLine(name + " is " + age);        // 拼接:+ 粘文本
Console.WriteLine(string.Format("{0} is {1}", name, age));  // 佔位符
Console.WriteLine($"{name} is {age}");         // 插值:$ + {…}

現在就練