C++의 데이터 열거를 진행하는 방법에 대한 이야기

#include <iostream>
using namespace std;

/* const로 상수를 설정하다보면 */
const int SCISSORS = 1;
const int ROCK = 2;
const int PAPER = 3;

/* 위에 작성된 것처럼 작성하기 마련이다.
하지만 의미 부여상으로 보면 저렇게 같은 성격을 가진 존재들끼리 하나로 묶는 개념이 필요하다. */


/* 그래서 나타난 개념이 바로 'ENUM'이다! */
enum ENUM_SPP
{
    ENUM_SCISSORS = 1,
    ENUM_ROCK,
    ENUM_PAPER
};

/* ENUM은 const에 비해 초기값을 설정하지 않아도 된다. (ENUM 과 const의 차이점) 

그럼 ENUM 값은 지정을 하지 않을 경우 어떻게 되는가?
숫자를 지정 안하면 첫 값은 0부터 시작한다. (즉, ENUM_SCISSORS = 0; 이라는 의미이다.)
그 다음의 값들은 이전 값에 + 1이 진행된다.

여기서 처음 값을 정한다면? 그 다음 값들도 같이 이전 값에 + 1이 된 상태로 빌드가 된다. */

/* 그렇다면 여기서 const 와 ENUM의 명확한 쓰임새와 차이점에 대해 알아보자.

1. const 의 경우, 메모리에 저장될 때, 되지 않을때가 있다.

일반적으로 const는 빌드를 진행할 때, 메모리에 주소값이 지정되어 있지 않다. 
F5를 눌러 확인해보면 [식은 lvalue 또는 함수 지정자여야 합니다.]로 출력될 것이다.

하지만 int main() 안에서 
auto a = &SCISSORS; 이런 경우, SCISSORS의 주소값을 auto a 에 넣어줬기에
메모리에 담겨 있는 모습을 확인할 수 있다. 
    
이를 조금 심화적으로 다루어 보자면 int main() 밖(data 영역)에 
선언한 const int ~~ 들은 메모리에 올라가지 않고 실행될 때, 
int main() 안에서 자신들이 쓰여진 부분에 자신들(변수)이 들어가는게 아니라 
자신의 값(1,2,3)등이 바로 들어가는 경우가 생긴다.

또는 int main() 안(Stack 영역)에
선언한 const int ~~ 들은 stack 영역에 올라가서 동작 방식으 달라질 수 있다.

또는 int main() 밖(data 영역)에
선언한 const int ~~ 을 int main() 안에서 
auto b = &ROCK; 처럼 선언한다면 이를 메모리에 할당하게 되는데, 
이 방법은 위에서 알게된 방법과 다르게 메모리를 더 소모하는 방향으로 진행된다.
(즉, 메모리의 과소모 = 낭비가 이루어질 수 있는 방법이다.) */

/* #이 붙은 개념 -> 전처리 지시문을 의미한다.
우리가 컴파일을 진행할 때, 1) 전처리 -> 2) 컴파일 -> 3) 링크
컴파일을 진행하기 전에 미리 컴파일 하기 쉽도록 거치는 단계 = 전처리

그럼 우리는 어디서 #을 사용하는 거지?!
우리는 CPP 파일을 만들 때, 항상 #include <iostream> 을 작성한다.
iostream 의 내용을 전부 긁어서 여기에 붙여주세요!! 라는 의미로 받아들이면 된다.

위에서 간단한 예시로 알아본 결과
DEFINE_SCISSORS 로 작성된 부분을 1이라는 값으로 넣어서 진행해주세요!! 라는 의미로 쓰여진다고 보면 된다.
*/
#define DEFIME_SCISSORS 1

/* const와 ENUM은 우리가 정수만 사용했었다. 놀랍게도 #define은 정수도 출력할 수 있다. */
#define DEFIME_TEST cout << "HELLO, WORLD"<< endl;

/* #define을 그렇게 추천하지 않는 이유가 있다고 한다.....
파일을 실행하면, 앞서 설명 했듯이 (우리가 컴파일을 진행할 때, 1) 전처리 -> 2) 컴파일 -> 3) 링크)
순서대로 진행이 된다. 그렇기에 전처리 단계에서 진행이 되는 #define을 디버깅해서 볼 때는, 결코 찾아볼 수 없다.

이유는 이미 컴파일을 진행할 당시 define에 정의한 변수들이 전부 define의 값으로 치환되어서 컴파일이 진행되었기에 
이를 찾아볼 수 없는 것이다. 

그렇기에 #define을 추천하지 않는 것이다.(물론 필요하고 적재적소인 부분에서는 사용하는 것이 맞다!)
 */

int main() {

    /* 그렇다면 여기서 ENUM에 대한 부분을 살펴보자 */
    int input;

    if (input = ENUM_SCISSORS) { cout << "SCISSORS" << endl; }
    /* 위처럼 ENUM_SCISSORS 로 작성된 부분에 제대로 된 ENUM_SCISSORS의 값이 들어가게 된다.
    이는 메모리를 낭비하는 일도 없으며 const로 선언한 data를 사용하는 방법보다 좋은 부분을 보여준다.
    
    하지만 현업에서는 상황에 따라서 const를 사용하는 경우도 있다보니 이렇게 간단하게 개념을 익히고 가자. */

}

댓글을 작성해보세요.