2강 · 제2장 · 약 55분
자료형과 선행처리기
상수·변수·자료형·오버플로와 #include/#define까지 PDF 없이도 핵심을 익힙니다.
학습 목표
- 상수(정수·실수·문자·문자열)와 변수의 차이를 설명한다
- 기본 자료형을 골라 변수를 선언·초기화하고 sizeof로 크기를 확인한다
- 대입(=)과 비교(==)를 구분한다
- 자료형 범위를 벗어나면 어떤 일이 생기는지(오버플로)를 이해한다
- 선행처리기(#include, #define, 조건부 컴파일)의 역할과 주의점을 안다
왜 이 강이 필요한가?
프로그램은 명령과 자료로 이루어집니다.
같은 숫자라도 int에 담을지 double에 담을지에 따라 차지하는 메모리·표현 범위·연산 방식이 달라집니다.
2강에서는 “자료를 어떤 그릇에 담을지”와, 컴파일 직전에 소스를 가공하는 선행처리기를 익힙니다.
1. 상수와 변수
| 상수(constant) | 변수(variable) | |
|---|---|---|
| 의미 | 한 번 정해지면 바꾸지 않는 값 | 이름이 붙은 기억 공간. 실행 중 값이 바뀔 수 있음 |
| 예 | 10, 3.14, 'A', "hi", #define PI 3.14, const int N = 3 | int score = 0; score = 95; |
변수 특징 세 가지: 이름, 자료형, 저장된 값.
1.1 정수형 상수
| 표기 | 예 | 규칙 |
|---|---|---|
| 10진 | 10, -99 | 0~9, 0으로 시작하지 않음 |
| 8진 | 011, 055 | 앞에 0 |
| 16진 | 0x2A, 0XFF | 앞에 0x / 0X |
| unsigned | 12u, 0xFAu | 뒤에 u/U |
1.2 실수형 상수
- 소수:
3.14,.5 - 지수:
12E3(=12000),5e-2(=0.05) - 기본 실수 리터럴은 보통
double float으로 쓰려면 뒤에f/F(3.14f)
1.3 문자·문자열 상수
- 문자: 작은따옴표 하나 —
'A'(내부적으로 ASCII 등 코드 값,'A'≈ 65) - 문자열: 큰따옴표 —
"Hi"
끝에는 보이지 않는 널 문자\0이 붙습니다.
예:"AB"→A,B,\0(3칸)
자주 쓰는 이스케이프 문자
| 표기 | 의미 |
|---|---|
\n | 줄바꿈 |
\t | 탭 |
\\ | 역슬래시 문자 |
\' | 작은따옴표 문자 |
\" | 큰따옴표 문자 |
\0 | 널(문자열 끝) |
1.4 변수 선언과 =의 의미
int a, b; /* 선언: int 크기 공간에 이름 a, b */
a = 100; /* 대입: a 자리에 100을 저장 */
b = 50;
C에서 = 는 “같다”가 아니라 대입(저장) 입니다.
“같은지 비교”는 == 입니다. (혼동하면 버그의 단골)
변수 이름 규칙은 1강의 식별자 규칙과 같습니다. 사용 전에 선언해야 합니다.
2. 자료형 — 그릇의 크기와 범위
자료형은 컴파일러에게 “이 이름으로 몇 바이트를 어떻게 해석할지” 알려 줍니다.
2.1 자주 쓰는 기본형 (대표값, 환경에 따라 다를 수 있음)
| 자료형 | 전형적 크기 | 대략적 범위(대표) | 용도 |
|---|---|---|---|
char | 1바이트 | 약 -128~127 (signed일 때) | 문자·작은 정수 |
short | 2바이트 | 약 -32768~32767 | 작은 정수 |
int | 흔히 4바이트 | 약 ±21억 | 기본 정수 |
long / long long | 4 또는 8바이트 등 | 더 큰 정수 | 큰 정수 |
float | 4바이트 | 대략적 실수 | 단정밀도 실수 |
double | 8바이트 | 더 정밀한 실수 | 기본 실수 |
unsigned … | 같거나 비슷 | 0 이상만, 양수 쪽 범위↑ | 음수가 필요 없을 때 |
정확한 크기는 환경마다 다를 수 있으므로, 코드에서 sizeof(타입) 으로 확인하는 습관이 좋습니다.
signed는 종종 생략하고, unsigned는 음수를 포기하는 대신 같은 비트로 더 큰 양수를 담습니다.
2.2 선언·초기화
int count; /* 선언만 — 지역이면 쓰레기 값일 수 있음 */
int score = 100; /* 선언 + 초기화 (권장) */
const double PI = 3.141592; /* 이후 대입 불가에 가깝게 사용 */
입문에서는 선언과 동시에 초기화하는 편이 안전합니다.
2.3 범위를 넘기면? (오버플로)
short의 최댓값 근처에서 +1 하면 예상과 다른 값(감싸짐)이 나올 수 있습니다.
→ 자료형을 목적에 맞게 고르고, 큰 수가 필요하면 int / long long 등을 씁니다.
3. 선행처리기 (Preprocessor)
실행 파일을 만들 때 순서는 대략:
선행처리 → 컴파일 → 링킹
선행처리기는 컴파일 전에 #로 시작하는 지시문을 처리합니다.
주의 (공통)
- 줄은
#로 시작 - 끝에 세미콜론을 붙이지 않음
- 보통 파일 맨 위(도입부) 에 둠
3.1 #include — 파일 포함
| 형식 | 찾는 위치(개념) |
|---|---|
#include <stdio.h> | 표준(시스템) 헤더 경로 |
#include "my.h" | 현재/지정 경로의 사용자 헤더 우선 |
stdio.h를 포함해야 printf 등의 선언을 쓸 수 있습니다.
자주 보는 헤더: math.h, string.h, stdlib.h, ctype.h, time.h …
3.2 #define — 매크로
매크로 상수
#define PI 3.141592
#define COURSE "C Programming"
- 이름은 보통 대문자
- 끝 세미콜론 없음
- 컴파일 전에 텍스트가 그대로 치환됨
매크로 “함수” (단순 치환 — 진짜 함수가 아님)
#define ADD(x, y) ((x) + (y))
인자·전체에 괄호를 권장합니다. 없으면 연산자 우선순위 때문에 결과가 달라질 수 있습니다.
예: #define HAP(x,y) x+y 일 때 10 * HAP(3,4) → 10 * 3 + 4 (=34)
괄호가 있으면 10 * ((3)+(4)) (=70)
const 변수와 #define 상수:
입문에서는 바뀌면 안 되는 값에 둘 다 쓸 수 있고, 타입 검사가 필요하면 const가 유리한 경우가 많습니다.
3.3 조건부 컴파일 (개념)
#if / #ifdef / #else / #endif 로 어떤 코드를 컴파일에 넣을지 고를 수 있습니다.
조건은 실행 중 변수가 아니라, 주로 매크로 값처럼 선행처리 시점에 알 수 있는 것이어야 합니다.
#define DEBUG 1
#if DEBUG
printf("debug on\n");
#endif
4. 지금 실습할 것
아래 코드에서:
- 그대로 실행해 출력·
sizeof결과 확인 year값을 바꾸고 다시 실행#define COURSE문자열을 수정해 보기- (선택)
ADD(2,3)결과를 출력하는 줄을 추가 - (선택)
short에 큰 수를 넣어 보고 이상한 값이 나오는지 관찰
printf 형식 미리보기: %d 정수, %f/%.2f 실수, %c 문자, %s 문자열, %zu는 sizeof 출력에 자주 사용(환경에 따라 %lu 등과 함께 쓰기도 함).
코드 실습 (C)
실행 결과가 여기에 표시됩니다.