정보처리기사 문제 풀이 중 헷갈리기 쉬운 Enum과 비트 연산 문제를 직접 풀이 흐름에 맞춰 다시 설명했습니다.
이 글은 정보처리기사 문제 풀이를 이어가며, 단순 암기보다 언어와 컴퓨터 구조가 어떻게 연결되는지 확인하려고 정리한 후속 기록이다. Enum의 내부 정수 매핑과 16진수 비트 연산은 시험 문제이면서 실제 프로그래밍 감각에도 꽤 도움이 되는 주제였다.
지난 글에 이어, 정보처리기사 문제들을 살펴보며 마주친 흥미로운 코드들을 두 번째로 정리해 본다. 언어마다 다른 듯 닮아있는 열거형(Enum)의 특성과, 컴퓨터 구조의 기초를 묻는 16진수 비트 연산 문제다.
1. 언어를 관통하는 열거형(Enum)
C#에서 자주 다루던 enum을 최근 C++에서도 보게 되었다. 사실 열거형은 Java, Python, JavaScript 등 다양한 언어에서 광범위하게 사용되는 개념이다.
열거형은 프로그래머가 직접 정의하는 ‘이름이 붙은 정수 상수들의 집합’이다. 숫자 0, 1, 2 대신 RED, GREEN, BLUE 같은 의미 있는 이름을 사용하여 코드의 가독성을 높여준다.
C++에서의 Enum 동작 방식
#include <iostream>
using namespace std;
int main()
{
enum spectrum {
red, orange, yellow, green, blue,
violet, indigo, ultraviolet
};
spectrum a = orange;
cout << a << endl;
int b;
b = blue;
b = blue + 3;
cout << b << endl;
}
이 코드의 출력 결과는 1과 7이다.
기본적으로 열거형은 첫 번째 요소부터 0, 1, 2 순서대로 정수값을 부여받는다. 흥미로운 점은 내부 요소에 디폴트 값을 명시할 때 나타난다. 만약 red = 3으로 지정한다면, 이어지는 orange는 4, blue는 7이 되어 최종 출력은 4와 10이 된다. 열거형이 순열처럼 순서대로 존재하며 메모리에 매핑된다는 사실을 알 수 있다.
Java에서의 Enum과 메서드 체이닝
Java에서의 Enum은 단순한 정수 상수를 넘어, 객체로서 더 많은 기능을 제공한다.
정보처리기사에서 나온 문제를 보자.
enum Tri {
A("A"), B("AB"), C("ABC");
private String code;
Tri(String code) {
this.code = code;
}
public String code() {
return code;
}
}
public class Main {
public static void main(String[] args) {
Tri t = Tri.values()[Tri.A.name().length()];
System.out.print(t.code());
}
}
출력 결과를 도출하기 위해서는 코드를 안쪽에서부터 해독해야 한다.
Tri.A.name():name()메서드는 enum 상수의 이름을 문자열로 반환한다. 즉,"A"를 반환한다..length(): 문자열"A"의 길이는1이다.Tri.values(): enum 상수들을 배열 형태{ A, B, C }로 반환한다.Tri.values()[1]: 배열의 인덱스 1에 해당하는 값은Tri.B이다.t.code():Tri.B생성 시 부여된 값인"AB"를 반환한다.
결과적으로 AB가 출력된다. 언어마다 Enum을 구현하고 활용하는 방식에 깊이 차이가 있음을 보여주는 좋은 예시다.
2. 16진수 비트 연산과 진법 변환
다음은 정처기 기출 유형 중에서, 단연 특이했던 16진수 배열 문제다. 컴퓨터 구조론 첫 단원에서 진법 변환을 배워서 문제로 풀곤했는데 이 문제를 처음 접하고 16진수가 코드에 나온다는게 친숙하면서 신선했다.
#include <stdio.h>
typedef struct student {
char* name;
int score[3];
} Student;
int dec(int enc) {
return enc & 0xA5;
}
int sum(Student* p) {
return dec(p->score[0]) + dec(p->score[1]) + dec(p->score[2]);
}
int main() {
Student s[2] = { "Kim", {0xA0, 0xA5, 0xDB}, "Lee", {0xA0, 0xED, 0x81} };
int result = 0;
for (int i = 0; i < 2; i++) {
result += sum(&s[i]);
}
printf("%d", result);
return 0;
}
이 문제의 핵심은 16진수를 2진수로 변환하여 비트 논리곱(AND, &) 연산을 수행한 뒤, 그 결과를 다시 10진수로 합산하는 과정에 있다. dec() 함수에서 기준이 되는 마스크 값은 0xA5 (2진수로 1010 0101)이다.
첫 번째 학생 (Kim) 연산
0xA0&0xA5:1010 0000&1010 0101=1010 0000(160)0xA5&0xA5: 동일한 값이므로1010 0101(165)0xDB&0xA5:1101 1011&1010 0101=1000 0001(129)- 합계: 160 + 165 + 129 = 454
두 번째 학생 (Lee) 연산
0xA0&0xA5: 이전과 동일하게1010 0000(160)0xED&0xA5:1110 1101&1010 0101=1010 0101(165)0x81&0xA5:1000 0001&1010 0101=1000 0001(129)- 합계: 160 + 165 + 129 = 454
최종 결과는 두 학생의 합산 값인 454 + 454 = 908이 된다.
정보처리기사 문제에 대한 글을 두번 나눠쓰면서 내가 굳이 제목에 정보처리기사 문제가 쓸모가 많다고 말한건, 이 글과 이전글에서 다뤘던 실기 문제들이 푸는 사람에게 의문점을 주고 헷갈리게 하려는 출제목적이 있기 때문에 쓸모가 많다고 느꼈다.
함수 포인터, Pass by Value, 메서드 체이닝, 진법 변환은 각각 포인터개념, 객체지향개념, 비트연산개념을 다루고 있으면서도 정확히 알지 못하면 틀리기 쉽고 나도 이렇게 글정리를 안하면 시간이 지나면 또 헷갈려 할 것 같다는 생각이 들었다.
댓글이 보이지 않으면 GitHub에 로그인한 뒤 새로고침해 주세요. 공개 댓글은 로그인 상태에서 더 안정적으로 표시됩니다.