###### tags: `CPP` # 13 使用列舉 (enumeration) 幫序號命名 使用陣列管理群組資料即使沒有要以循序的方式使用資料, 也有可以統一管理資料的好處, 不過如果單以序號來取用資料, 可能會不容易理解個別資料項目的意義, 例如若是我們只想在最亮與微微亮之間變化, 程式可以寫成以下這樣: ```cpp= const int led_pin = 5; struct twinkle_data { int pin; // LED 腳位 int duration; // 亮/熄總時長 int duration_on; // 亮燈時長 (us) int total; // 切換次數 }; twinkle_data twinkle_datas[] = { {led_pin, 100, 5, 10000}, // LED 微光 1s {led_pin, 100, 30, 5000}, // LED 稍亮 0.5s {led_pin, 100, 100, 2000} // LED 全亮 0.2s }; void twinkle(twinkle_data &data) { for(int count = 0;count < data.total; count++) { digitalWrite(data.pin, LOW); delayMicroseconds(data.duration_on); digitalWrite(data.pin, HIGH); delayMicroseconds(data.duration - data.duration_on); } } void setup() { pinMode(led_pin, OUTPUT); } void loop() { twinkle(twinkle_datas[2]); twinkle(twinkle_datas[0]); } ``` 由於是使用序號來指定資料項目, 所以如果不回頭看陣列內容, 我們並不會知道序號 2 和 0 的項目到底哪個比較亮?為了解決這個問題, 我們可以另外定義代表個別序號的變數, 並且為變數取一個具有說明意義的名稱, 例如: ```cpp= const int led_pin = 5; struct twinkle_data { int pin; // LED 腳位 int duration; // 亮/熄總時長 int duration_on; // 亮燈時長 (us) int total; // 切換次數 }; twinkle_data twinkle_datas[] = { {led_pin, 100, 5, 10000}, // LED 微光 1s {led_pin, 100, 30, 5000}, // LED 稍亮 0.5s {led_pin, 100, 100, 2000} // LED 全亮 0.2s }; int shimmer = 0, brighter = 1, brightest = 2; void twinkle(twinkle_data &data) { for(int count = 0;count < data.total; count++) { digitalWrite(data.pin, LOW); delayMicroseconds(data.duration_on); digitalWrite(data.pin, HIGH); delayMicroseconds(data.duration - data.duration_on); } } void setup() { pinMode(led_pin, OUTPUT); } void loop() { twinkle(twinkle_datas[brightest]); twinkle(twinkle_datas[shimmer]); } ``` 第 16 行就是額外建立的變數, 並且在第 32~33 行改用變數的值當序號存取陣列內的資料。 上述作法雖然可以改進單純用序號不具說明意義的問題, 不過我們必須自己設定個別變數的值, 如果數值設定錯誤, 就會存取到錯誤的資料項目。為了解決這個問題, 可以改用[**列舉 (enumeration)**](https://en.cppreference.com/w/cpp/language/enum), 像是這樣: ```cpp= const int led_pin = 5; struct twinkle_data { int pin; // LED 腳位 int duration; // 亮/熄總時長 int duration_on; // 亮燈時長 (us) int total; // 切換次數 }; twinkle_data twinkle_datas[] = { {led_pin, 100, 5, 10000}, // LED 微光 1s {led_pin, 100, 30, 5000}, // LED 稍亮 0.5s {led_pin, 100, 100, 2000} // LED 全亮 0.2s }; enum { shimmer, brighter, brightest }; void twinkle(twinkle_data &data) { for(int count = 0;count < data.total; count++) { digitalWrite(data.pin, LOW); delayMicroseconds(data.duration_on); digitalWrite(data.pin, HIGH); delayMicroseconds(data.duration - data.duration_on); } } void setup() { pinMode(led_pin, OUTPUT); } void loop() { twinkle(twinkle_datas[brightest]); twinkle(twinkle_datas[shimmer]); } ``` 第 16~18 就是列舉, 編譯器會自動幫我們從 0 開始編號, 所以 `shimmer` 會是 0、`brighter` 就是 1, 而 `brightest` 則是 2。在第 34、35 行就使用列舉的名稱來取用陣列中的資料。 利用列舉, 我們就可以幫序號取具有說明意義的名稱, 而且也不會編錯序號。