Enum, Set

2009. 9. 9. 15:36언어/C++ Builder

볼랜드 포럼에서 퍼왔습니다. 이걸로서 한시름 놓을까요? ㅋ

 

녕하세요? 민 입니다.

이 강좌는 "C++ Builder에서는 Set을 어떤 식으로 사용하고 있을까" 에
대하여 궁금해 하고 계시는 분들의 궁금증을 말끔히 씻어드리고자 준비한
강좌입니다.
또한 이 강좌를 읽으시면 C++ 언어의 열거(enum)형 상수, C++ Builder의
Set에 대해서도 아실 수 있습니다.

일단 enum형 상수(열거형 상수)에 대해 아셔야 하므로 설명드리면
다음과 같습니다.

열거형 상수(Enumerated Constants)를 이용하면 새로운 형(type)을 만드실
수 있습니다. 또한 이 새로운 형이 갖게 될 값도 여러분이 원하시는 것으로
할 수 있습니다.

COLOR라는 이름을 가지고 RED, BLUE, GREEN, WHITE, BLACK 이렇게 다섯개의
값을 가질 수 있는 열거형을 만들려면 다음과 같이 하면 됩니다.

enum COLOR { RED, BLUE, GREEN, WHITE, BLACK };

위 구문이 어떤 기능을 하는지 다시 정리해 보면 다음과 같습니다.

1. COLOR가 열거형의 이름, 곧 새로운 형이 되도록 합니다.
2. RED를 0의 값을 가지는 기호 상수가 되게 하고, BLUE는 1의 값을 가지는
    기호 상수로, GREEN은 2의 값을 가지는 기호 상수로, 나머지도 동일한
    순서로 되게 합니다.

다시 말하면 위와 같이 하게 되면 맨 처음에 주어진 상수(RED)는 0의
값을 가지며 뒤로 하나씩 가면서 1씩 증가한 값을 갖게 된다는 거죠.
0, 1, 2, 3, 4, 5, 6, 7, .........
(위에서 언급한 대로 모든 열거형 상수는 '정수(int)' 값을 갖게 됩니다.)

보통 위와 같이 사용하지만, 또다른 쓰임에 대해 알아보도록 합시다.
(읽기 귀찮으시다면 그냥 다음으로 넘어가셔도 됩니다. ^^)
이제 0, 1, 2, 3.. 이런 식으로 열거형 상수가 값을 갖도록 하지 말고
열거형 상수에 우리가 값을 매겨보도록 합시다.

enum COLOR { RED=100, BLUE, GREEN=500, WHITE, BLACK=700 };

위와 같이 특정 열거형 상수(RED, GREEN, BLACK)만이 값을 따로 지정할
수도 있으면 아니면 모든 열거형 상수(RED, BLUE, GREEN, WHITE, BLACK)가
값을 갖도록 할 수도 있습니다.

위와 같은 구문에서 RED에서부터 BLACK은 각각 무슨 값을 갖느냐?
참 궁금하지요?

정답은 "초기화되지 않은 것들은 그 이전의 값에서 커지는 쪽으로 매겨진다."
입니다.

그러니까 위는 다음과 같이 값을 갖죠.
RED는 100으로 초기화 되었으니 100을 갖고, BLUE는 초기화된 것인 앞의
RED로 부터 1 증가한 값인 101을 갖습니다. 그러면 WHITE는 몇을 값으로
가질까요?  맞습니다. GREEN(500)에서 1증가한 값인 501을 갖습니다.

COLOR라는 우리가 새로 정의한 enum형 변수는 하나의 값만을 가질 수 있습니다.

int a;
a = 10;

이런식으로 int형도 하나의 값만을 가집니다. enum형의 경우도 다음과 같이
할 수는 없는 것과 마찬가지입니다.

a = 100, 101;

그리고 COLOR라는 열거형 변수가 실제로는 unsigned int 형이라는 것을
아는 것이 중요하며, 열거형 상수들이 '정수 변수'와 같다는 것을 알아야만
합니다.
위와 같은 이유로 실제로 열거형 변수에 정수값을 넣을 수도 있습니다.
('넣는다'는 표현을 다른 말로 하면 '할당한다'라고 할 수 있지요 ^^)
실제로 열거형 변수에 정수값을 넣어 보시면 제대로 작동을 하고
다만 경고(warning)가 발생한다는 것을 알 수 있을 겁니다.
(컴파일러나 컴파일러의 경고관련 설정에 따라 경고가 발생하지 않을 수도
  있습니다.)

위와 같이 열거형을 사용하게 되면, 그냥 int color; color = 1; 이런 식으로
코딩하는 것에 비해 휠씬 좋은 방법이라는 사실을 알 수 있습니다.
(위와 같이 하면 1이 어떤 색상의 값인지 직관적으로 알 수 없기 때문입니다.)

위의 열거형은 C++에서 새로 추가된 것입니다. 그러면 C 언어 시절에는
어떤 방식을 사용했을까요? 다음과 같이 define 상수를 사용했습니다.

#define RED   0
#define BLUE  1
#define GREEN 2
#define WHITE 3
#define BLACK 4

int color;
color = WHITE;

(실제로 C 언어로 작성되거나, C++로 작성되었지만 불행히도 열거형에 대해
  모르는 사람이 작성한 소스를 보시면 많이 보게 되는 코드입니다.)

자자 이제 enum 형에 대해 충분히 다루었다고 생각이 됩니다.
(괜히 너무 길게 썼나 싶을 정도로...)

마지막으로 enum 형의 쓰임에 관한 예제를 하나 들고 enum에 대한 이야기는
마치도록 하겠습니다.

----------------------------------------------------------------------
#include <iostream.h>

int main()
{
     enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday,
                 Friday, Saturday };

     Days DayOff;
     int x;

     cout << "What day would you like off (0-6)? ";
     cin  >> x;
     DayOff = Days(x);  // 새로운 기법(?)이죠? ^^;

     if (DayOff == Sunday || DayOff == Saturday)
         cout << "\nYou're already off on weekends!\n";
     else
         cout << "\nOkay, I'll put in the vacation day.\n";

    return 0;
}
----------------------------------------------------------------------


아래는 Set에 관한 설명입니다.

1. Set 의 기원.

    '파스칼(pascal)'이라고 하는 언어에는 set 이라고 하는 집합 기능을
    수행하는 편리한 형이 존재합니다. 실제로 오브젝트 파스칼을 사용하는
    델파이 같은 경우는 set 형을 사용하는 것을 볼 수 있습니다.
    그러나 C/C++ 언어에서는 집합에 대한 내장 지원 기능이 없습니다.
    ( C/C++ 프로그래머들은 집합 기능을 사용하기 위해 비트필드(bitfield)
      라는 기법을 사용합니다. )
    델파이와의 호환성을 위해, 그리고 set형의 편리함 때문에 씨빌더
    개발자들은 Set 이라고 하는 템플릿(template) 클래스를 만들게 되었습니다.

2. Set 구문의 의미.

    Set<type, minval, maxval>

    파라미터  설명
    ----------------------------------------------------------------------
    type      Set의 원소들(elements)의 타입
              (보통 int, char, 또는 열거(enum)형이 사용된다.)
    minval
              Set이 담을 수 있는 최소 값 (이 값은 0보다 작을 수 없습니다.)
    maxval
              Set이 담을 수 있는 최대 값 (이 값은 255보다 클 수 없습니다.)
    ----------------------------------------------------------------------

3. Set형 선언, 생성의 두가지 방법.

    Set형은 다음과 같이 두가지 방법으로 선언이 가능합니다.

    Set <char,'A','Z'> s1;
    Set <char,'A','Z'> s2;
    Set <char,'A','Z'> s3;

    위와 같이 똑같은 Set에 대한 다수의 인스턴스(instance)를 생성할 때에는
    다음과 같이 C 언어서부터 존재해오던 'typedef'를 같이 사용하게 되면
    휠씬 편합니다.

    typedef Set <char,'A','Z'> CharSet;

    CharSet s1;
    CharSet s2;
    CharSet s3;


자, 이제 이번 강좌의 주제인 "C++ Builder에서는 Set을 어떤 식으로
사용하고 있을까" 에 대해 설명하도록 하겠습니다.

씨빌더 IDE 환경에서 프로퍼티 익스펙터에 있는 여러 프로퍼티들 중에
프로퍼티명 앞에 '+' 자가 붙여져 있는 것들을 볼 수 있습니다.

그것들의 대부분이 Set을 사용하고 있습니다.
(도움말에서 직접 확인해 보십시요.)

DBGrid의 'Options'를 사용하는 것을 예로 들어 보도록 하겠습니다.

DBGrid1의 Set형 프로퍼티인 Options의 dgEditing을 true로 설정하려면
다음과 같이 하면 됩니다.

DBGrid1->Options = DBGrid1->Options << dgEditing;

반대로 DBGrid1의 Options의 dgEditing을 false로 설정하려면?

DBGrid1->Options = DBGrid1->Options >> dgEditing;

'>>', '<<' 연산자는 C++ 언어 공부를 하셨다면 많이 보셨을 겁니다.
(Set 이라는 것이 클래스로 구현되어 있고, 이 Set이라는 클래스에서
  '>>', '<<' 연산자를 오버로딩한 것으로 보입니다.)

위에서 Set의 한 원소(위의 예에서는 dgEditing)을 true나 false로
설정한다는 의미는 그 Set에서 그 원소가 있느냐 없느냐(다시 말하면
그 Set에 그 원소가 속하냐 속하지 않느냐)를 결정하는 것입니다.

자 다음으로.. DBGrid1->Options 중에 dgEditing이 true로 설정되어 있는지
(다시 말하면 DBGrid1->Options에 dgEditing이 속하느냐 속하지 않느냐)를
알고 싶다면 다음과 같이 하면 됩니다.

DBGrid1->Options.Contains( dgEditing );

Contains라는 Set 클래스의 멤버함수(메서드)는 true 혹은 false를
리턴합니다.

자.. 그렇다면 위에서 다룬 DBGrid1의 Set형 프로퍼티인 Options의
실체를 보도록 할까요?
(이것을 위해서 위에서 힘들게(헉~ 3페이지가 넘어가는 설명이군요)
  enum과 Set에 대하여 설명한 것입니다.)

enum TDBGridOption { dgEditing, dgAlwaysShowEditor, dgTitles, dgIndicator,
                      dgColumnResize, dgColLines, dgRowLines, dgTabs,
                      dgRowSelect, dgAlwaysShowSelection, dgConfirmDelete,
                      dgCancelOnExit,dgMultiSelect };

typedef Set<TDBGridOption, dgEditing, dgMultiSelect>  TDBGridOptions;

아마 위의 enum에 대한 설명과 Set에 대한 설명을 잘 읽으셨다면 위 코드가
무슨 의미인지 잘 아실리라 믿습니다. 그러므로 설명은 생략하도록 하겠습니다.

자.. 이제 이것으로 "C++ Builder에서는 Set을 어떤 식으로 사용하고 있을까"
에 대한 강좌를 마칠까 합니다.
아무쪼록 많은 도움이 되었길 진심으로 바랍니다.


덧 ) 이 글은 나우누리 내의 씨빌더 프로그래머들을 위한 최고의 소모임인
      나우누리 씨빌더 소모임(go sgcccc) 강좌란의
     '장원섭(장dander)'님이 쓰신 '[강좌] c++빌더4.0 100일 왕초보와..(4)'
      라는 글을 보충하기 위한 목적으로 나우누리 씨빌더 소모임 한 곳에만
      올려 집니다. (추후에 제가 딴 곳에 올릴 수도 있지만 현재로서는..)
      혹시(정말 혹시..) 자신이 속한 다른 프로그래밍 동호회에 이 글을 올리고
      싶으시다면 갈무리(캡쳐)한 '있는 그대로' 올려 주시기 바랍니다.

덧 두번째 ) 위 글에서 틀림점이 있다면 가차없이 제게 메일 주십시요.

---[참고자료]-------------------------------------------------------------
"teach yourself C++"  Jesse Liberty | 정경희. 비앤씨.
"초보자를 위한 볼랜드 C++ 빌더 3"  Kent Reisdorph | 장해인. 인포북.
"[답변] 기본적인 Set형의 사용법과 제작"
      이진수(XENON).  하이텔 비주얼파워툴(vtool) C++ Builder Q&A 게시판.
"씨빌더 온라인 도움말"
-------------------------------------------------------------------------

'언어 > C++ Builder' 카테고리의 다른 글

C++ 유용한 사이트  (0) 2010.08.09
C++ builder윈도우 서비스  (0) 2009.09.25
쓰레드 기초.  (0) 2009.09.07
쓰레드를 이용한 채팅 서버 만들기.  (0) 2009.09.04
C++ Builder Component 설치 하기.  (0) 2009.09.01