목차
- 변수
- 출력 형식
- 연산자
- 제어문과 반복문
- 핵심 요약
변수
변수의 종류
변수는 선언된 위치와 생존 기간에 따라 지역변수, 전역변수, 정적변수, 동적 할당 변수로 나눌 수 있다.
| 종류 | 저장 영역 | 소멸 시점 | 초기화 하지 않았을 때 |
| 지역변수 | 스택 | 함수 실행 시 생성, 함수 종료 시 소멸 | 불확정 값 |
| 전역변수 | 정적 저장 영역 | 프로그램 시작 시 생성, 종료 시 소멸 | 0으로 초기화 |
| 정적변수 | 정적 저장 영역 | 프로그램 시작 시 생성, 종료 시 소멸 | 0으로 초기화 |
| 동적 할당 변수 | 힙 | 할당 후 직접 반환할 때까지 유지 | 불확정 값 |
지역변수 Local Variable
함수 또는 블록 내부에서 선언하는 변수다.
void func(void) {
int a = 10;
}
- 일반적으로 스택 영역에 저장된다.
- 함수가 호출되면 생성되고, 함수 실행이 끝나면 소멸한다.
- 선언만 하고 값을 넣지 않으면 불확정 값이 들어 있다.
- 선언된 함수 또는 중괄호 블록 내부에서만 사용할 수 있다.
void func(void) {
int a = 10;
printf("%d\n", a);
}
// printf("%d", a); // 오류: func 내부의 지역변수라 접근 불가
전역변수 Global Variable
모든 함수 바깥에서 선언하는 변수다.
#include <stdio.h>
int a = 10;
int main(void) {
printf("%d\n", a);
return 0;
}
- 정적 저장 영역에 저장된다.
- 프로그램이 시작될 때 생성되고, 프로그램이 종료될 때 소멸한다.
- 명시적으로 초기화하지 않아도 기본적으로 0으로 초기화된다.
- 선언된 파일 내의 여러 함수가 공유해서 사용할 수 있다.
- 여러 함수가 같은 값을 수정할 수 있으므로, 너무 많이 사용하면 흐름을 추적하기 어려워진다.
int count;
void increase(void) {
count++;
}
int main(void) {
increase();
increase();
printf("%d\n", count); // 2
return 0;
}
정적변수 Static Variable
static 키워드를 붙여 선언하는 변수다.
void func(void) {
static int a = 0;
a++;
printf("%d\n", a);
}
- 정적 저장 영역에 저장된다.
- 프로그램이 종료될 때까지 값이 유지된다.
- 초기화는 프로그램 실행 중 한 번만 수행된다.
- 함수를 여러 번 호출해도 이전 호출에서 변경된 값이 유지된다.
- 초기값을 지정하지 않으면 0으로 초기화된다.
#include <stdio.h>
void func(void) {
static int a = 0;
a++;
printf("%d\n", a);
}
int main(void) {
func(); // 1
func(); // 2
func(); // 3
return 0;
}
일반 지역변수였다면 func()가 호출될 때마다 a가 새로 만들어져 매번 1이 출력된다.
하지만 static 지역변수는 한 번 만들어진 뒤 계속 유지되므로 1 → 2 → 3으로 증가한다.
static은 변수의 수명은 길게 유지하면서, 지역변수처럼 함수 내부에서만 접근하게 만들 수 있다.
동적 할당 변수 Dynamic Allocation
실행 중 필요한 크기만큼 메모리를 확보해서 사용하는 방식이다.
int *p = /* 동적 할당으로 확보한 int 저장 공간 */;
- 힙 영역에 저장된다.
- 프로그램 실행 중 필요한 시점에 메모리를 확보할 수 있다.
- 사용이 끝난 메모리는 반드시 반환해야 한다.
- 초기화하지 않은 공간에는 불확정 값이 들어 있을 수 있다.
- 반환하지 않고 계속 참조를 잃어버리면 메모리 누수가 발생할 수 있다.
동적 할당은 실행 전에 크기를 정확히 알기 어려운 배열, 연결 리스트, 트리 같은 자료구조를 만들 때 자주 사용한다.
int n;
scanf("%d", &n);
// 실행 중 입력받은 n에 맞춰 저장 공간을 준비하는 상황
지역변수와 정적 지역변수 비교
void local_func(void) {
int a = 0;
a++;
printf("%d\n", a);
}
void static_func(void) {
static int a = 0;
a++;
printf("%d\n", a);
}
local_func(); // 1
local_func(); // 1
local_func(); // 1
static_func(); // 1
static_func(); // 2
static_func(); // 3
| 구분 | 지역변수 | 정적 지역면수 |
| 생성 시점 | 함수 호출 시 | 프로그램 시작 시 |
| 소멸 시점 | 함수 종료 시 | 프로그램 종료 시 |
| 함수 재호출 시 값 | 새로 생성됨 | 이전 값 유지 |
| 접근 범위 | 선언된 함수 또는 블록 내부 | 선언된 함수 또는 블록 내부 |
자료형
변수는 값을 저장하기 위한 이름이 붙은 메모리 공간이다.
int age = 25;
char grade = 'A'; -> 문자 하나는 작은따옴표
char str[] = "Hello"; -> 문자열 큰따옴표
float height = 165.5f;
double pi = 3.141592;
| int | 정수 | 10, -3 |
| char | 문자 1개 | 'A', 'b' |
| float | 실수 | 3.14f |
| double | 더 정밀한 실수 | 3.141592 |
| void | 값이 없음 | 반환값 없는 함수 |
출력 형식: printf
printf는 화면에 값을 출력하는 함수다.
printf("Hello\n");
자주 쓰는 형식 지정자는 다음과 같다.
| %d | 정수 int | printf("%d", 10); |
| %c | 문자 char | printf("%c", 'A'); |
| %s | 문자열 | printf("%s", "Hello"); |
| %f | 실수 float, double | printf("%f", 3.14); |
| %x | 16진수 정수 | printf("%x", 255); |
| %p | 주소값 | printf("%p", ptr); |
int age = 25;
char grade = 'A';
double score = 95.5;
printf("나이: %d\n", age); // 25
printf("등급: %c\n", grade); // A
printf("점수: %.1f\n", score); // 95.5
printf("%x", 255); // ff
%.1f는 소수점 아래 한 자리까지만 출력한다.
printf("%.2f", 3.14159); // 3.14
줄바꿈은 \n이다.
printf("A\n");
printf("B\n");
출력 결과:
A
B
연산자
산술 연산자
int a = 10;
int b = 3;
a + b; // 13
a - b; // 7
a * b; // 30
a / b; // 3
a % b; // 1
정수끼리 나누면 결과도 정수다.
printf("%d", 10 / 3); // 3
나머지는 %를 사용한다.
printf("%d", 10 % 3); // 1
증감 연산자
int i = 1;
i++; // i = i + 1
i--; // i = i - 1
전위 연산은 먼저 증감하고 사용한다.
int i = 1;
printf("%d", ++i); // 2
후위 연산은 먼저 사용하고 증감한다.
int i = 1;
printf("%d", i++); // 1
printf("%d", i); // 2
비교 연산자
비교 결과는 참이면 1, 거짓이면 0으로 취급된다.
a == b; // 같다
a != b; // 다르다
a > b; // 크다
a < b; // 작다
a >= b; // 크거나 같다
a <= b; // 작거나 같다
주의: =는 대입, ==는 비교다.
int a = 3; // 대입
a == 3; // 비교
논리 연산자
&& // 그리고(AND)
|| // 또는(OR)
! // 부정(NOT)
int age = 25;
int hasTicket = 1;
if (age >= 19 && hasTicket) {
printf("입장 가능");
}
삼항 연산자
조건에 따라 두 값 중 하나를 선택할 때 사용한다.
조건 ? 참일 때 값 : 거짓일 때 값;
int score = 80;
char grade = score >= 60 ? 'P' : 'F';
printf("%c", grade); // P
if ~ else를 짧게 쓰는 표현이라고 생각하면 된다.
int max = a > b ? a : b;
제어문과 반복문
if ~ else
조건이 참이면 if 블록을 실행하고, 거짓이면 else 블록을 실행한다.
if (조건) {
실행문;
} else {
실행문;
}
C에서는 0을 거짓으로, 0이 아닌 모든 값을 참으로 취급한다.
if (0) {
printf("실행 안 됨");
}
if (-1) {
printf("실행됨");
}
중괄호는 실행문이 한 줄일 때 생략할 수 있다.
if (1)
printf("A");
하지만 중괄호를 생략하면 바로 다음 한 문장만 if의 영향을 받는다.
if (1)
printf("A");
printf("B");
출력 결과:
AB
아래 코드도 printf("B");는 조건문과 상관없이 실행된다.
if (1)
printf("A");
printf("B");
가독성과 실수를 막기 위해 중괄호를 쓰는 습관이 안전하다.
if (1) {
printf("A");
printf("B");
}
switch
하나의 값에 따라 여러 경우를 나눌 때 사용한다.
switch (값) {
case 값1:
실행문;
break;
case 값2:
실행문;
break;
default:
실행문;
}
case는 값이 일치하는 위치로 이동한다.
break를 만나면 switch문을 종료한다.
break가 없으면 다음 case까지 계속 실행된다. 이것을 fall-through라고 한다.
#include <stdio.h>
int main() {
int num = 2;
switch (num) {
case 1:
printf("ONE\n");
break;
case 2:
printf("TWO\n");
// break 없음
case 3:
printf("THREE\n");
break;
default:
printf("DEFAULT\n");
}
return 0;
}
출력 결과:
TWO
THREE
num이 2이므로 case 2부터 실행된다.
그런데 case 2에 break가 없으므로 case 3까지 이어서 실행된다.
default는 항상 실행되는 것이 아니다.
switch (num) {
case 1:
printf("ONE");
break;
case 2:
printf("TWO");
break;
default:
printf("DEFAULT");
}
- num == 1이면 ONE
- num == 2이면 TWO
- 어느 case에도 해당하지 않으면 DEFAULT
for
반복 횟수가 비교적 명확할 때 자주 사용한다.
for (초기값; 조건; 증감식) {
실행문;
}
for (int i = 0; i < 5; i++) {
printf("%d ", i);
}
출력 결과:
0 1 2 3 4
실행 순서는 다음과 같다.
초기값 → 조건 확인 → 실행문 → 증감식 → 조건 확인 → ...
while
조건이 참인 동안 반복한다.
while (조건) {
실행문;
}
int i = 0;
while (i < 5) { // 5보다 작은 동안 반복
printf("%d ", i);
i++;
}
출력 결과:
0 1 2 3 4
while문에서는 반복 조건을 바꾸는 코드가 빠지면 무한 루프가 될 수 있다.
int i = 0;
while (i < 5) {
if (i == 2) {
continue;
}
i++;
}
위 코드는 i == 2가 되면 continue로 반복문의 처음으로 돌아간다.
하지만 i++가 실행되지 않으므로 i는 계속 2에 머물고 무한 반복된다.
수정하려면 증가를 먼저 처리하거나, continue 전에 증가시켜야 한다.
int i = 0;
while (i < 5) {
if (i == 2) {
i++;
continue;
}
i++;
}
do ~ while
조건을 나중에 검사하므로 do 블록은 최소 한 번은 무조건 실행된다.
do {
실행문;
} while (조건);
int i = 10;
do {
printf("%d", i);
} while (i < 5);
출력 결과:
10
조건 i < 5는 거짓이지만, 조건을 검사하기 전에 do 블록을 먼저 실행했기 때문이다.
break와 continue
break는 반복문 또는 switch문을 즉시 종료한다.
for (int i = 0; i < 10; i++) {
if (i == 5) {
break;
}
printf("%d ", i);
}
출력 결과:
0 1 2 3 4
continue는 현재 반복만 건너뛰고 다음 반복으로 넘어간다.
for (int i = 0; i < 5; i++) {
if (i == 2) {
continue;
}
printf("%d ", i);
}
출력 결과:
0 1 3 4
핵심 정리
지역변수: 함수가 실행되는 동안만 존재
전역변수: 프로그램 전체에서 공유 가능
정적변수: 프로그램 끝까지 값 유지, 초기화는 한 번만 동적
할당 변수: 실행 중 필요한 크기만 확보하고 사용 후 반환 필요
%d: 정수 출력
%c: 문자 출력
%s: 문자열 출력
%f: 실수 출력
%x: 16진수 출력
%p: 주소값 출력
if: 조건이 참일 때 실행
switch: 값에 따라 여러 분기 처리
for: 반복 횟수가 명확할 때 사용
while: 조건이 참인 동안 반복
do while: 실행문을 최소 한 번은 실행
break: 반복문 또는 switch 종료
continue: 현재 반복만 건너뛰고 다음 반복 진행'정보처리기사' 카테고리의 다른 글
| [정처기] 03. C언어 배열, 포인터 +연습문제 (0) | 2026.06.27 |
|---|---|
| [정처기] 02. C언어 함수, 재귀 +연습 문제 (0) | 2026.06.26 |
| [정처기] 01-1. C언어 변수, 연산자, 출력 형식, 제어문 & 반복문 연습문제 (0) | 2026.06.26 |
| 정처기 공부해라 (0) | 2026.06.24 |