---
# System prepended metadata

title: 07 使用自製函式減少重複的程式碼
tags: [Arduino, CPP]

---

###### tags: `CPP` `Arduino`

# 07 使用自製函式減少重複的程式碼

在上一個教學中, 你可能已經注意到漸亮和漸暗的過程切換亮/熄的程式其實是一樣的, 如果可以減少重複的程式, 就可以讓程式更精簡。要做到這一點, 可以使用自製的函式。

到目前為止, 除了 Arduino 規定的 `setup` 與 `loop` 外, 我們都是使用 Arduino 提供的函式, 接著就來試試將切換亮/熄的程式包裝成函式：

```cpp=
const int total = 200;    // 亮/熄切換總次數
const int duration = 100; // 單次亮/熄時長 (us)
const int led_pin = 5;    // 內建 LED 腳位 

void twinkle(int led_pin, int duration, int duration_on, int total) {
  for(int count = 0;count < total; count++) {
    digitalWrite(led_pin, LOW);
    delayMicroseconds(duration_on);
    digitalWrite(led_pin, HIGH);
    delayMicroseconds(duration - duration_on);
  }
}
 
void setup() {
  pinMode(led_pin, OUTPUT);
}

void loop() {
  for(int duration_on = 0; duration_on <= duration; duration_on++) {
    twinkle(led_pin, duration, duration_on, total);
  }
  for(int duration_on = duration; duration_on >= 0; duration_on--) {
    twinkle(led_pin, duration, duration_on, total);
  }
}
```

第 5~12 就是自訂的函式：

1. 函式名稱前面要註明**傳回值的資料型別**, **`void`** 表示這個函示**沒有運算結果**, **不會傳回值**。如果你的函式是計算圓的面積這樣的功能, 就需要傳回以浮點數表示的面積, 最前面就要標示型別為 [`float`](https://www.arduino.cc/reference/en/language/variables/data-types/float/)。

1. 這個函式名稱為 `twinkle`, 後面的小括號內要註明呼叫這個函式時要**傳入哪些參數**, 參數之間用逗號隔開。此例需要傳入 4 個整數, 分別代表 LED 的腳位編號、單次切換亮/熄的總時長 (單位 us)、亮燈的時長 (單位 us) 以及切換的次數。

1. 7~11 行就跟之前的程式一樣, 不再贅述。

1. 第 20 和 23 行就是呼叫這個自訂函式, 呼叫時就會把傳入的資料一一對應將其內容複製到函式內的參數, 然後執行函式的區塊, 以本例來說, 就是 6~11 行的迴圈, 跳離迴圈後就會結束函式, 回到呼叫位置, 再從下一個敘述接續執行。

透過自訂的函式, 我們就可以讓需要重複使用到的程式碼只出現一次, 並且在需要用到的地方改成呼叫函式, 不但可以讓程式更精簡, 若是為函式**取個好名字**, 還可以讓程式的語意更清楚, 像是本例的 'twinkle' 字義就是閃爍, 你不需要知道函式實際的內容也能猜出它的作用。

:::info
要特別注意的是, 本例中的函式參數名稱雖然都和函式外的變數名稱一樣, 不過函式的參數是獨立專屬於函式的一份變數, 和函式外的變數並不相干, 只是透過呼叫函式將資料傳入。

如果覺得這樣容易混淆, 可以幫參數取不一樣的名字, 或是在名稱前加上 '\_' 做區隔。
:::
