C언어 진수 변환과 비트 연산
🔥 매회 출제 (priority 3)
🌱 왜 배우나
사람은 손가락이 열 개라서 숫자를 0~9까지 세다 한 자리를 올린다. 이게 10진수(decimal)다. 컴퓨터는 전기 스위치의 켜짐·꺼짐, 딱 두 상태만 안다. 그래서 0과 1만 쓰는 2진수(binary)가 컴퓨터의 모국어다. 2진수는 금방 길어지니까, 네 자리를 한 글자로 줄인 16진수(hexadecimal)가 따라붙는다. 웹 색상 코드 #FF5733이나 메모리 주소를 16진수로 쓰는 이유다. 진수 변환을 모르면 코드가 출력한 0x1A가 무슨 값인지 읽을 수가 없다.
📖 핵심 개념
진수는 “숫자를 몇 개의 기호로 세는가”를 정하는 약속이다. 10진수는 09, 2진수는 01, 8진수(octal)는 07, 16진수는 09와 A~F를 쓴다.
10진수를 다른 진수로 바꾸는 공식은 한 줄이다. “그 진수의 밑(base)으로 계속 나누고, 나머지를 역순으로 읽는다.” 예를 들어 87을 16진수로 만들면, 87÷16=5 나머지 7, 5÷16=0 나머지 5다. 역순으로 읽으면 “57”. 왜 역순일까. 처음 구한 나머지가 1의 자리, 그 다음이 16의 자리이기 때문이다.
printf의 서식 문자(format specifier)를 쓰면 변환이 더 쉽다. %d는 10진수, %o는 8진수, %x·%X는 16진수다(소문자·대문자).
비트 연산자는 정수를 2진수로 놓고 자릿수(비트)끼리 논리 계산한다. AND(&)는 둘 다 1일 때만 1. OR(|)는 하나만 1이어도 1. XOR(^, exclusive or)는 서로 다를 때만 1. NOT(~)은 0과 1을 뒤집기. 시프트(<<, >>)는 비트를 좌우로 밀어서 곱하기 2, 나누기 2 효과를 낸다.
🔍 시각화
┌─────────── 10진수 87 → 16진수 변환 ───────────┐
│ │
│ 87 ÷ 16 = 5 나머지 7 → hex[0] = '7' │
│ 5 ÷ 16 = 0 나머지 5 → hex[1] = '5' │
│ │
│ 역순 출력: 5 7 → "57" │
└────────────────────────────────────────────────┘
┌─────────── 비트 AND 연산 ─────────────────────┐
│ a = 0x1A → 0 0 0 1 1 0 1 0 (26) │
│ b = 0x0F → 0 0 0 0 1 1 1 1 (15) │
│ ────────────────────────────── │
│ a & b → 0 0 0 0 1 0 1 0 (0A = 10) │
│ (둘 다 1인 자리만 1) │
└───────────────────────────────────────────────┘
┌─────────── 왼쪽 시프트 ───────────────────────┐
│ c = 3 → 0 0 0 0 0 0 1 1 │
│ c << 2 → 0 0 0 0 1 1 0 0 (12 = 3×4) │
│ (비트가 왼쪽으로 2칸 이동, 빈자리는 0) │
└───────────────────────────────────────────────┘
↔️ 이웃 개념 구분
- 진수 변환 vs 비트 연산: 진수 변환은 같은 숫자를 다른 표기법으로 바꾸는 일. 비트 연산은 2진수 자릿수를 직접 조작하는 일.
<<시프트 vs*곱셈:n << k는n × 2^k와 결과가 같다. 다만 비트를 미는 전용 연산이라 곱셈보다 빠르다.- 0x 접두어 vs
%X서식:0x1A는 코드에 16진수를 적는 표기.%X는 출력할 때 16진수로 찍는 서식.
🔑 핵심 용어
- 진수(numeral system): 숫자를 몇 개의 기호로 세느냐를 정하는 방식
- printf 서식:
%d(decimal, 10진수),%o(octal, 8진수),%x/%X(hexadecimal, 16진수) - 0x 접두어: 16진수 리터럴(코드에 직접 쓴 값)을 나타냄.
0x1A= 26 - 0 접두어: 8진수 리터럴을 나타냄.
010= 8 - 비트 AND(
&): 두 비트 모두 1이면 1, 그 외 0 - 비트 OR(
|): 하나라도 1이면 1 - 비트 XOR(
^, exclusive or): 서로 다르면 1, 같으면 0 - 비트 NOT(
~): 모든 비트를 반전(0→1, 1→0) - 왼쪽 시프트(
<<): 비트를 왼쪽으로 이동.n << 1은 n × 2 - 오른쪽 시프트(
>>): 비트를 오른쪽으로 이동.n >> 1은 n ÷ 2(몫)
✅ 스스로 가르쳐보기
진수라는 말을 처음 듣는 친구에게 “10진수 200을 16진수로 바꾸는 이야기”를 들려준다면 어떻게 말하시겠어요? 본인만의 비유(예: 동전 바꾸기, 자릿수 올림) 하나를 넣어 한 문장 정의부터 만들어 보세요.
체크포인트:
- 왜 하필 16으로 나누는지 이유를 말할 수 있는가
- 나머지가 10 이상일 때 A~F로 바꾸는 이유를 설명할 수 있는가
- 나머지를 역순으로 읽어야 하는 이유를 말할 수 있는가
- 200을 직접 계산해 C8이 나오는 과정을 보여줄 수 있는가
🎯 기출 포인트
- 2025-1회: 10진수 → 16진수 변환 코드 출력 추적 (답: 908). 기출파괴 포인트로 수험생 다수 오답
- 출제 패턴: while문으로 나머지 연산 반복 → 역순 출력. 진수 변환 원리를 코드로 구현
- 비트 연산: AND/OR/XOR/시프트 연산 결과 추적. 2진수로 변환 후 비트별 계산
- 주의:
%X는 대문자,%x는 소문자 16진수 출력