맨위로가기

열거형

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

열거형은 프로그래밍에서 관련된 상수들을 묶어 코드의 가독성과 유지보수성을 높이는 데 사용되는 자료형이다. 매직 넘버 사용을 줄여 코드의 의미를 명확하게 하고 오류 발생 가능성을 낮추는 장점이 있다. 열거형은 각 언어별로 구현 방식이 다르며, C, C++, C#, Java 등 다양한 언어에서 지원된다. 데이터베이스에서도 ENUM 타입을 통해 열거형을 지원하기도 한다.

2. 개념 및 장점

열거형은 서로 관련 있는 상수들을 묶어서 이름을 붙여 사용하는 것이다. 이렇게 하면 코드의 가독성이 좋아지고, 유지보수하기가 쉬워진다.[1]

예를 들어, 카드 한 벌에 있는 네 개의 수트는 '클럽', '다이아몬드', '하트', '스페이드'와 같이 네 개의 열거자로 나타낼 수 있으며, 이들은 '수트'라는 열거형에 속한다. 만약 'V'라는 변수가 '수트'라는 데이터 유형으로 선언되었다면, 이 변수에는 네 가지 값 중 하나를 할당할 수 있다.

열거형을 사용하면 '매직 넘버'(코드 내에서 특별한 의미 없이 사용되는 숫자)를 사용하는 것을 줄일 수 있다. 이는 코드를 이해하기 쉽게 만들고, 오류 발생 가능성을 낮춘다.

또한, 열거형을 사용하면 컴파일러가 코드의 의미가 올바른지 검사할 수 있어, 타입 안정성이 높아진다. 예를 들어,

```

myColor = TRIANGLE

```

와 같은 코드는 금지될 수 있지만,

```

myColor = RED

```

는 ''TRIANGLE''과 ''RED''가 내부적으로 ''1''로 표현되더라도 허용된다.

개념적으로 열거형은 각 값에 고유한 숫자가 할당된 명목 숫자 목록과 유사하다. 만약 순서가 의미가 있거나 비교에 사용된다면, 열거형은 서수 타입이 된다.

2. 1. 명명 규칙

열거형에 할당된 변수는 일반적으로 단수형 명사이며, 흔히 파스칼 표기법 또는 대문자 표기법을 따르고, 소문자 및 기타 표기법은 덜 사용된다.[1]

3. 프로그래밍 언어별 구현

C의 구문을 계승하는 언어는 대부분 열거형을 지원한다. 하지만 Perl이나 JavaScript와 같은 동적 타입 언어는 일반적으로 열거형을 직접 지원하지 않는다.

3. 1. 파스칼 계열

파스칼에서는 괄호 안에 값을 나열하여 열거형을 선언한다. 에이다에서는 `=` 대신 `is`를 사용하여 열거형을 정의한다.

파스칼 계열 언어에서 열거 값의 순서는 중요하며, `pred` 및 `succ` 함수를 사용하여 이전 또는 다음 값을 얻을 수 있다. `ord` 함수는 열거 값을 정수 표현으로 변환한다. 표준 파스칼은 산술형에서 열거형으로의 변환을 지원하지 않지만, 확장 파스칼이나 다른 파생 언어에서는 이 기능을 제공하기도 한다. 예를 들어, Modula-3에서는 `VAL` 메서드를 사용하여 변환을 수행한다.

파스칼 스타일 언어는 열거형을 배열 인덱스로 사용할 수 있다. 에이다는 `Pred`, `Succ`, `Val`, `Pos` 외에도 `Image` 및 `Value`를 통해 문자열 변환을 지원하며, 열거형의 내부 표현 및 비트 수를 지정할 수 있다. 또한, `Boolean` 및 `Character`를 미리 정의된 열거형 타입으로 취급하며, 자체 문자 타입도 정의할 수 있다.

3. 1. 1. 파스칼 예제

파스칼에서 열거형은 괄호 안에 값을 나열하여 암시적으로 선언할 수 있다.

```pascal

var

suit: (clubs, diamonds, hearts, spades);

```

여러 변수에 사용할 수 있도록 열거형 선언은 `type`을 사용한 타입 시노님(별칭) 선언에 자주 나타난다.

```pascal

type

cardsuit = (clubs, diamonds, hearts, spades);

card = record

suit: cardsuit;

value: 1 .. 13;

end;

var

hand: array [ 1 .. 13 ] of card;

trump: cardsuit;

```

열거 값의 순서는 작성된 순서가 된다. 열거형은 순서형 ordinal type영어이며, `Pred`, `Succ` 함수는 열거의 앞 또는 다음 값을 제공하고, `Ord`는 열거 값을 정수 표현으로 변환한다. 그러나 표준 파스칼에서는 숫자형에서 열거형으로의 변환은 할 수 없다. 확장 파스칼은 확장된 `Succ` 함수를 통해 이 기능을 제공한다. 다른 파스칼 파생 언어의 일부에서는 형변환으로 변환 가능한 것도 있다.

3. 1. 2. 에이다 예제

에이다에서 `=`의 사용은 "is"로 대체된다.

```ada

type Cardsuit is (clubs, diamonds, hearts, spades);

```

에이다는 `Pred`, `Succ`, `Val` 및 `Pos` 외에도 `Image` 및 `Value`를 통한 간단한 문자열 변환을 지원한다.

C 스타일 언어와 유사하게 에이다는 열거형의 내부 표현을 지정할 수 있다.

```ada

for Cardsuit use

(clubs => 1, diamonds => 2, hearts => 4, spades => 8);

```

C 스타일 언어와 달리 에이다는 열거형의 비트 수도 지정할 수 있다.

```ada

for Cardsuit'Size use 4; -- 4 비트

```

또한 파스칼처럼 열거형을 배열의 인덱스로 사용할 수 있지만, 열거형에 대해 정의된 속성이 있다.

```ada

Shuffle : constant array(Cardsuit) of Cardsuit :=

(Clubs => Cardsuit'Succ(Clubs), -- 열거형 속성 보기 'First, 'Last, 'Succ, 'Pred

Diamonds => Hearts, -- 명시적 값

Hearts => Cardsuit'Last, -- Cardsuit 타입의 첫 번째 열거형 값, 예를 들어 clubs

Spades => Cardsuit'First -- Cardsuit 타입의 마지막 열거형 값, 예를 들어 spades

);

```

Modula-3와 마찬가지로 에이다는 `Boolean` 및 `Character`를 특수한 미리 정의된 (패키지 " `Standard` "에 있는) 열거형 타입으로 취급한다. Modula-3과 달리 자체 문자 타입도 정의할 수 있다.

```ada

type Cards is ('7', '8', '9', 'J', 'Q', 'K', 'A');

3. 2. C 계열

C에서는 `enum` 키워드를 사용하여 열거형을 정의한다. C++(C++)에서는 C의 열거형을 상속하며, `enum class`를 통해 범위가 지정된 열거형(scoped enumeration)을 사용할 수 있다. C#에서 열거형은 `System.Enum`에서 파생되는 값 형식이며, C와 유사한 의미 체계를 가진다. Java에서는 열거형이 특수한 클래스로 취급되며, 열거형 값은 해당 클래스의 인스턴스로 동작한다.

C의 초기 버전에는 열거형이 없었지만, ANSI C(C89) 표준에서 추가되었다. C에서는 `enum` 키워드를 사용하여 열거형을 정의하며, 이는 구조체 및 공용체 정의와 유사한 형태를 가진다. C는 열거형 값의 정수 표현을 프로그래머에게 직접 노출하며, 정수와 enum 값은 자유롭게 혼합될 수 있다. 또한, 프로그래머가 열거형 상수의 값을 명시적으로 지정할 수도 있다.[1]

C++는 C에서 열거형을 직접 상속받았지만, C++에서 열거형은 실제 타입으로 취급되어 컴파일 시간에 추가적인 검사를 제공한다. C++11에서는 `enum class`를 통해 범위가 지정된 열거형을 제공하며, 이는 타입 안전성을 높이고 열거자가 암시적으로 정수 타입으로 변환되는 것을 방지한다.[12]

C#의 열거형은 C와 유사한 의미 체계를 가지지만, 일부 산술 연산은 열거형에 대해 정의되지 않는다. 열거형 값은 정수로 명시적으로 변환하거나, 정수에서 열거형으로 변환할 수 있다. 또한, C#은 열거형에 특정 정수 값을 정의할 수 있는 기능을 제공하여, 열거형 값을 플래그 집합으로 처리할 수 있도록 한다.[3][4][5][6]

Java에서 열거형은 Java SE (J2SE) 버전 5.0부터 도입되었다. Java의 열거형은 특수한 클래스로 취급되며, 열거형 값은 해당 클래스의 미리 생성된 인스턴스로 동작한다. 모든 열거형 타입은 암묵적으로 `java.lang.Enum` 추상 클래스를 상속한다.[8][9][13]

3. 2. 1. C 예제

C의 초기 버전인 K&R C에는 열거형이 없었으나, ANSI C(C89) 표준에서 추가되었다.[1] C에서 열거형은 `enum` 키워드를 사용하여 정의하며, 구조체 및 공용체 정의와 유사한 형태를 가진다. `enum` 키워드 자체는 저장 공간 할당을 유발하지 않는다.[1]



enum cardsuit {

Clubs,

Diamonds,

Hearts,

Spades

};

struct card {

enum cardsuit suit;

short int value;

} hand[13];

enum cardsuit trump;



C는 열거형 값의 정수 표현을 프로그래머에게 직접 노출한다. 정수와 enum 값은 자유롭게 혼합될 수 있으며, enum 값에 대한 모든 산술 연산이 허용된다. 심지어 enum 변수가 열거형에 정의되지 않은 값을 가질 수도 있다. 실제로 언어 정의에 따르면, 위 코드는 `Clubs`, `Diamonds`, `Hearts`, `Spades`를 `int` 유형의 상수로 정의하며, 해당 유형의 변수에 저장될 경우에만 (자동으로) `enum cardsuit`로 변환된다.

C는 또한 프로그래머가 열거형 상수의 값을 명시적으로 선택할 수 있도록 허용한다. 예를 들면 다음과 같다.



enum cardsuit {

Clubs = 1,

Diamonds = 2,

Hearts = 4,

Spades = 8

};



위 코드는 비트 단위 논리 연산을 통해 카드 무늬 집합을 `enum cardsuit`로 나타낼 수 있는 형을 정의하는 데 사용될 수 있다.

C23부터 열거형의 기본 유형을 프로그래머가 지정할 수 있다.[2]



enum cardsuit : char {

Clubs = 1,

Diamonds = 2,

Hearts = 4,

Spades = 8

};


3. 2. 2. C++ 예제

C++는 C에서 직접 상속받은 열거형을 가지고 있으며, 대부분 C의 열거형과 동일하게 작동하지만, C++에서는 열거형이 실제 타입이므로 컴파일 시간에 추가적인 검사를 제공한다.[12] 또한 (구조체와 마찬가지로) C++ `enum` 키워드는 `typedef`와 결합되어, `enum name`으로 타입을 명명하는 대신, 단순히 `name`으로 명명할 수 있다.

```c++

enum cardsuit {

CLUBS,

DIAMONDS,

HEARTS,

SPADES // C++11 이후에서는 마지막 요소 뒤에 콤마를 붙여도 된다.

};

int a = DIAMONDS; // 암묵적으로 대입 가능.

cardsuit b = DIAMONDS;

cardsuit c = 1; // 컴파일 에러.

```

C++에서는 빈 구조체를 정의할 수 있는 것과 마찬가지로 빈 열거체도 정의할 수 있다.

```c++

enum SomeEnum {}; // 컴파일 가능.

```

C++11은 ''범위가 지정된 열거형''이라는 두 번째 종류의 열거형을 제공한다. 이는 타입 안전하며, 열거자는 정수 타입으로 암시적으로 변환되지 않는다. 범위가 지정된 열거형은 `enum class` (또는 `enum struct`) 구문으로 지정된다.

```c++

enum class Cardsuit { Clubs, Diamonds, Spades, Hearts };

int a = Cardsuit::Hearts; // 컴파일 에러.

Cardsuit b = Cardsuit::Hearts;

```

범위가 지정된 열거형의 또 다른 특징은 열거자가 유출되지 않으므로, `using enum` 선언(C++20에서 도입됨)을 사용하여 열거자를 현재 범위로 가져오지 않는 한, 열거형의 이름으로 접두사를 붙여 사용해야 한다 (예: 위의 예제의 `Cardsuit::Hearts`).[12]

열거형의 ''기본 타입''은 모든 열거된 값을 저장할 수 있을 만큼 충분히 큰 구현 정의 정수 타입이며, 가능한 가장 작은 타입일 필요는 없다. 기본 타입을 직접 지정할 수 있으며, 이를 통해 열거형의 "전방 선언"이 가능하다.

```c++

enum class Color : long {Red, Green, Blue}; // 'long' 타입의 크기와 메모리 레이아웃에 맞아야 함

enum class Shapes : char; // 전방 선언. 나중에 'char'에 맞지 않는 값이 정의되면 오류가 발생

3. 2. 3. C# 예제

C# 프로그래밍 언어의 열거형은 C 열거형의 "작은 정수" 의미 체계 대부분을 보존한다. 일부 산술 연산은 열거형에 대해 정의되지 않지만, 열거형 값은 정수로 명시적으로 변환될 수 있으며, 다시 원래 열거형으로 변환될 수 있다. 또한 열거형 변수는 열거형 정의에 의해 선언되지 않은 값을 가질 수 있다.[3] 예를 들어,

```csharp

enum Cardsuit

{

Clubs,

Diamonds,

Spades,

Hearts

}

```

`CardSuit.Diamonds + 1`과 `CardSuit.Hearts - CardSuit.Clubs` 표현식은 직접 허용된다 (값의 시퀀스를 단계별로 진행하거나 두 값 사이의 단계 수를 묻는 것이 의미가 있을 수 있기 때문). 그러나 `CardSuit.Hearts * CardSuit.Spades`는 덜 의미가 있다고 간주되며, 값을 먼저 정수로 변환해야만 허용된다.

C#은 열거형에 특정 정수 값을 정의할 수 있는 C와 유사한 기능을 제공한다. 이렇게 하면 열거형에 대해 이진 연산을 수행하여 열거형 값을 플래그 집합으로 처리할 수 있다. 이러한 플래그는 이진 연산을 사용하거나 열거형 타입의 내장 메서드를 사용하여 테스트할 수 있다.[4][5][6]

열거형 정의는 선택한 정수 값에 대한 이름을 정의하며, 이는 구문적 설탕이다. 열거형 정의의 범위에 없는 다른 정수 값을 열거형 변수에 할당할 수 있기 때문이다.

또한, `FlagsAttribute`를 지정함으로써, 비트 연산이 허용된다.

```csharp

/// 빛의 삼원색을 1bit씩 나타낸다

[Flags]

enum RgbColor : byte {

Black = 0,

Red = 1,

Green = 2,

Blue = 4,

Cyan = Green | Blue,

Magenta = Blue | Red,

Yellow = Red | Green,

White = Red | Green | Blue,

}

3. 2. 4. Java 예제

자바는 Java SE (J2SE) 버전 5.0부터 열거형을 도입했다.[8]

```java

// 열거형의 상수 기호는 모두 대문자로 하는 것이 관례이다.

enum Cardsuit { CLUBS, DIAMONDS, SPADES, HEARTS }

...

Cardsuit trump = Cardsuit.CLUBS;

```

자바의 타입 시스템은 열거형을 정수와 분리된 타입으로 취급하며, enum영어 값과 정수 값의 혼합 연산은 허용되지 않는다. ( 메서드를 사용하여 enum 값의 정수 표현을 얻을 수 있다.)[9] 사실, 자바의 enum 타입은 산술 타입이 아닌 컴파일러가 생성한 특수한 클래스이며, enum 값은 해당 클래스의 미리 생성된 전역 인스턴스로 동작한다. enum 타입은 인스턴스 메서드와 생성자(인수가 각 enum 값을 분할 지정할 수 있다)를 가질 수 있다. 모든 enum 타입은 암묵적으로 추상 클래스를 상속한다. enum 타입을 직접 인스턴스화하는 것은 허용되지 않는다. 각 열거형에는 정적 메서드 `values()`가 암묵적으로 정의되어 열거형에 포함된 모든 상수의 집합을 배열로 얻을 수 있다.[13]

3. 3. 기타 언어

이나 자바스크립트 같은 동적 타입 언어들은 C의 문법 전통을 따르지만, 일반적으로 열거형을 직접 지원하지 않는다. 그러나 펄에서는 스트링 리스트해시를 사용하여 열거형과 유사한 결과를 얻을 수 있다.[7]

Go는 `iota` 키워드를 사용하여 열거형 상수를 생성한다.[7]

Haxe는 열거형을 지원한다.

Groovy는 동적 타입 언어이지만, Java에서 유래된 열거형을 지원한다.

Common Lisp는 형식 지정자 `member`를 사용한다.

VBA의 열거형은 자동으로 "정수" 데이터 형식으로 할당되며, 그 자체로 데이터 형식이 될 수 있다.

Python의 경우 enum 모듈을 사용하여 열거형을 정의한다.

Ruby는 모듈을 사용하여 열거형과 유사한 기능을 구현할 수 있다.

Kotlin은 열거형을 지원하며, `enum class` 키워드를 사용한다.

Scala는 `Enumeration` 객체를 상속하여 열거형을 정의한다.

TypeScript는 JavaScript에 '열거형(enum)' 데이터 형식을 추가한다.

3. 3. 1. Python 예제

파이썬 표준 라이브러리에는 버전 3.4부터 enum 모듈이 추가되었다.

```python

from enum import Enum

class Cards(Enum):

CLUBS = 1

DIAMONDS = 2

HEARTS = 3

SPADES = 4

```

자동으로 생성된 인덱스(1부터 시작)로 열거형을 생성하기 위한 [https://docs.python.org/3.4/library/enum.html#functional-api 기능적 API]도 있다.

```python

Cards = Enum("Cards", "CLUBS DIAMONDS HEARTS SPADES")

```

파이썬 열거형은 의미론적 정확성을 강제하지 않는다(호환되지 않는 열거형과의 무의미한 비교는 `TypeError`를 발생시키는 대신 항상 ''False''를 반환한다).

```pycon

>>> Color = Enum("Color", "RED GREEN BLUE")

>>> Shape = Enum("Shape", ["CIRCLE", "TRIANGLE", "SQUARE", "HEXAGON"])

>>> def has_vertices(shape):

... return shape != Shape.CIRCLE

...

>>> has_vertices(Color.GREEN)

True

```

```python

from enum import Enum

class Cardsuit(Enum):

clubs = 1

diamonds = 2

hearts = 3

spades = 4

3. 4. 함수형 언어

haskell

datatype cardsuit = Clubs | Diamonds | Hearts | Spades

type card = { suit: cardsuit; value: int }

val hand : card list

val trump : cardsuit

```

ML 계열 (예: SML, OCaml, Haskell)의 함수형 프로그래밍 언어에서는 대수적 데이터 타입을 사용하여 열거형을 구현할 수 있다. 예를 들어 SML 시그니처 문법으로 위와 같이 표현할 수 있다.

ML 계열 언어에서는 작은 정수 표현이 구현에 사용되더라도 프로그래머에게는 완전히 숨겨진다. Haskell에서는 ''Enum'' 타입 클래스를 통해 타입과 ''Int'' 간의 매핑을 얻는 구현을 할 수 있다.

4. 데이터베이스

일부 데이터베이스는 열거형을 직접 지원한다. MySQL은 `ENUM` 타입을 사용하여 열거형을 정의할 수 있고, PostgreSQL에서는 `CREATE ENUM` 구문을 사용하여 열거형을 정의할 수 있다. XML 스키마는 열거형 패싯(enumeration facet)을 통해 열거형을 지원한다.[10]

4. 1. MySQL 예제

MySQL은 테이블을 만들 때 문자열로 지정된 허용 가능한 값에 대해 `ENUM` 열거형을 제공한다. 값은 숫자 인덱스로 저장되며, 빈 문자열은 0, 첫 번째 문자열 값은 1, 두 번째 문자열 값은 2 등으로 저장된다. 값은 숫자 인덱스 또는 문자열 값으로 저장하고 검색할 수 있다.[10]

예시:

```mysql

CREATE TABLE shirts (

name VARCHAR(40),

size ENUM('x-small', 'small', 'medium', 'large', 'x-large')

);

참조

[1] 서적 The C Programming Language https://archive.org/[...] Prentice Hall 1978-02
[2] 웹사이트 WG14-N3030 : Enhancements to Enumerations https://open-std.org[...] 2022-07-19
[3] 웹사이트 Enum.HasFlag(Enum) Method (System) https://learn.micros[...] 2024-12-06
[4] 웹사이트 A Comparison of Microsoft's C# Programming Language to Sun Microsystems' Java Programming Language http://www.25hoursad[...] 2012-09-06
[5] 웹사이트 Java 5: Taming the Tiger: Syntactic Sugar http://www.cstruter.[...] Fachhochschule Aargau, Nordwestschweiz 2012-09-10
[6] 웹사이트 Syntactic sugar (C#): Enum http://www.cstruter.[...] CSTrüter 2012-09-10
[7] 웹사이트 Effective Go http://golang.org/do[...] The Go Authors 2014-05-13
[8] 웹사이트 Enum Types http://docs.oracle.c[...] Oracle 2013-12-05
[9] 서적 Effective Java https://archive.org/[...] Addison-Wesley
[10] 웹사이트 MySQL :: MySQL 8.0 Reference Manual :: 11.3.5 The ENUM Type https://dev.mysql.co[...] 2021-09-19
[11] PDF ISO/IEC 9899:yyyy - n2346.pdf https://www.open-std[...]
[12] PDF C++ International Standard - n3337.pdf https://www.open-std[...]
[13] 웹사이트 列挙型 - Oracle Java SE 8 Documentation https://docs.oracle.[...]



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com