C++ 中的列舉型別

Jinku Hu 2023年1月30日 2021年6月28日
  1. C++ 中的無作用域列舉
  2. C++ 中的作用域列舉
C++ 中的列舉型別

本文將演示如何在 C++ 中使用列舉型別。

C++ 中的無作用域列舉

一段時間以來,列舉一直是 C 語言的一部分。C++ 還通過一些附加功能實現了相同的概念。通常,列舉是命名常量整數的機制。程式設計師定義列舉器名稱。整數值可以明確指定或通過給定名稱的位置推斷。

列舉是使用關鍵字 enum 確定的,它們可以選擇定義型別的名稱(例如,以下程式碼片段中的 Color)。請注意,C++ 列舉常量具有實現定義的整數型別。因此,如果給定值需要比 int 更大的空間,則選擇相應的整數型別作為基礎型別。型別也可以由使用者在列舉名稱後顯式指定,需要用單個冒號分隔(如本文第四個程式碼段所示)。

在下面的示例中,我們定義了一個名為 Color 的列舉,並將六種顏色名稱指定為列舉常量。由於這些常量都沒有分配給它們的顯式值,因此積分值是從它們的位置從零開始推匯出來的。這段程式碼實現了一個顏色到字串的轉換函式,它僅限於給定的值。變數 Color 也是一個無作用域的列舉;這意味著它的列舉器(常量)可以從與列舉本身相同的範圍訪問。

#include <iostream>

using std::cout;
using std::endl;
using std::string;

enum Color { RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW };

string ColorToString(Color c) {
    switch(c) {
        case RED: return "Red";
        case BLUE: return "Blue";
        case GREEN: return "Green";
        case CYAN: return "Cyan";
        case MAGENTA: return "Magenta";
        case YELLOW: return "Yellow";
        default: return "NAN";
    }
}

int main() {
    Color col1 = RED;

    cout << "the given color is " << ColorToString(col1) << endl;

    return EXIT_SUCCESS;
}

輸出:

the given color is Red

或者,我們可以定義一個列舉(例如 WeekDay),其中每個列舉器都具有明確分配的整數值。你可以利用此功能來實現可以根據不同日期約定進行修改的靈活結構。如果需要,可以在同一個列舉物件中混合顯式值和位置值。

#include <iostream>

using std::cout;
using std::endl;

enum WeekDay { MON = 1, TUE = 2, WED = 3, THU = 4,
            FRI = 5 , SAT = 6, SUN = 7 };

int main() {
    auto today = SAT;
    cout << "today is " << today << "th day" << endl;

    return EXIT_SUCCESS;
}

輸出:

today is 6th day

C++ 中的作用域列舉

列舉的另一個有用的特性是有一個作用域;因此,它被稱為作用域列舉。後一個可以使用 enum classenum struct 關鍵字宣告。作用域列舉遵循通常的作用域約定,並且不能在列舉作用域之外訪問。從好的方面來說,全域性範圍的列舉不會像非範圍的列舉那樣導致名稱衝突。

下一個程式碼示例將上一個示例中的 WeekDay 定義為作用域列舉。請注意,可以使用 cout 函式作為任何其他變數來列印無作用域列舉,但需要將作用域列舉轉換為相應的整數值。

#include <iostream>

using std::cout;
using std::endl;

enum class WeekDay { MON = -1, TUE = 2, WED = 3, THU = 4,
    FRI = 5 , SAT = 6, SUN = 7 };

int main() {
    auto today = WeekDay::MON;
    cout << "today is " << static_cast<unsigned>(today) << "th day" << endl;

    return EXIT_SUCCESS;
}

輸出:

today is 6th day

與無作用域的列舉相比,有作用域的列舉必須有一個名稱。另一方面,作用域列舉沒有預設的底層整數型別。請注意,將列舉數強制轉換為不同型別時,底層型別轉換可能會導致溢位。

#include <iostream>

using std::cout;
using std::endl;

enum class WeekDay : int { MON = -1, TUE = 2, WED = 3, THU = 4,
    FRI = 5 , SAT = 6, SUN = 7 };

int main() {
    auto today = WeekDay::MON;
    cout << "today is " << static_cast<unsigned>(today) << "th day" << endl;

    return EXIT_SUCCESS;
}

輸出:

today is 4294967295th day
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相關文章 - C++ Enum