1. C# 的函式/方法
你已經學了不少 C# 指令,所以你可以寫出蠻複雜的程式了。10、20、30 行的程式碼——這樣的程式其實不算大,對吧?
但如果程式有 100+ 行,那就真的大了,要看懂就有點頭痛。那有沒有辦法讓寫大程式、讀大程式變簡單一點?
有啦,這時候 方法(函式) 就派上用場了。
那什麼是方法?簡單說,方法就是一組有自己名字的指令。換句話說,就是把幾個指令包成一組,給它一個獨一無二的名字。這樣一來,一個方法就搞定了。
假設你有一段畫貓的程式碼:
Console.WriteLine(" |\\__/,| (`\\");
Console.WriteLine(" |o_o |__ _) )");
Console.WriteLine(" (____/ (_/ ");
它會輸出這樣:
|\__/,| (`\
|o_o |__ _) )
(____/ (_/
你可以把它搬到一個獨立的方法裡,想畫幾隻貓就畫幾隻:
void WriteCat()
{
Console.WriteLine(" |\\__/,| (`\\");
Console.WriteLine(" |o_o |__ _) )");
Console.WriteLine(" (____/ (_/ ");
}
//畫三隻貓
WriteCat();
WriteCat();
WriteCat();
當程式執行時,每次執行 WriteCat(),它就會跑一次 WriteCat() 裡面的所有指令。我們只是把幾個指令包成一個新指令(方法)。
函式的意義:
- 把程式分成幾塊,每塊各自處理自己的事。
- 重複利用超方便:寫一次,想用幾次就用幾次。
- 減少 bug:函式有 bug 只要改一個地方。
- 給複雜動作取名字——程式碼一看就懂。
術語:函式、方法、程序
在 C# 裡,函式 跟 方法 基本上是一樣的,但還是有點小差別。
- 方法——屬於 class 或物件的函式(C# 幾乎全部都是方法)。
- 程序——不會回傳值的函式(void 方法)。
- 函式——廣義來說,就是任何有名字、可以呼叫的程式區塊。
官方說法是 C# 裡這些都叫 方法,但如果你之後看到「函式」也不用怕啦!
2. 方法宣告語法:逐步拆解
來看個最簡單的函式例子,就是經典的 "Hello, World!",不過我們把輸出動作丟到一個方法裡:
using System;
class Program
{
static void Main()
{
PrintHello();
}
static void PrintHello() // 輸出 Hello, World!
{
Console.WriteLine("Hello, World!");
}
}
語法拆解:
| 部分 | 範例 | 說明 |
|---|---|---|
| 修飾詞 | |
表示這個方法屬於 class(細節後面再說) |
| 回傳型別 | |
表示這個方法不會回傳任何東西 |
| 方法名稱 | |
呼叫這個方法用的名字 |
| 參數 | |
引數(空的就是沒引數) |
| 方法主體 | |
呼叫時會執行的程式碼 |
比喻:
方法就像咖啡機:你投錢(引數),按按鈕(呼叫方法),咖啡機煮咖啡(方法主體),然後給你結果(回傳值)——如果是 void 方法就沒東西給你啦!
3. 怎麼呼叫方法
呼叫方法超簡單,就是名字加括號就好:
PrintHello(); // 沒參數的方法
int sum = Add(2, 3); // 有參數、有回傳值的方法
重點: 你只能在方法宣告之後(或是在它上面,或同一個 class 裡)呼叫它。
4. 有參數的方法
方法可以傳參數進去,這樣方法就很彈性,什麼情況都能用。其實參數就是方法裡的變數,呼叫時會給它們值。宣告方法時要寫好參數。
static void Greet(string name)
{
Console.WriteLine($"哈囉, {name}!");
}
// 用法:
Greet("愛莉絲");
Greet("鮑伯");
參數——就是你呼叫方法時要給它的變數。
| 部分 | 範例 | 說明 |
|---|---|---|
| 參數型別 | |
要傳進來的值的型別 |
| 參數名稱 | |
在方法裡用的名字 |
呼叫:
Greet("愛莉絲");——name 會拿到 "愛莉絲" 這個值。
多個參數
可以用逗號宣告多個參數:
static void PrintSum(int a, int b)
{
Console.WriteLine($"總和: {a + b}");
}
// 用法:
PrintSum(5, 7); // 總和: 12
5. 值參數跟參考參數
方法的參數就是普通變數,規則跟其他變數一樣。
所以要記得:你把陣列傳進方法時,其實是傳 參考,也就是方法可以改到原本的陣列內容。簡單型別(int、double)則是傳值。
static void ZeroFirstGrade(int[] grades)
{
grades[0] = 0; // 會改到原本的陣列!
}
// 用法:
int[] a = {1, 2, 3, 4, 5};
ZeroFirstGrade(a);
Console.WriteLine(a[0]); //會輸出 0
其實這裡發生的事就像這樣:
static void ZeroFirstGrade(int[] grades)
{
grades[0] = 0; // 會改到原本的陣列!
}
// 用法:
int[] a = {1, 2, 3, 4, 5};
//ZeroFirstGrade(a);
int[] grades = a;
grades[0] = 0;
Console.WriteLine(a[0]); //會輸出 0
GO TO FULL VERSION