변수(variable)는 값을 담아 두는 이름 붙은 칸이고, printf는 따옴표 안 글자의 %d·%c·%s 자리에 값을 끼워 화면에 찍는 함수입니다. 실기의 코드 문제는 출력을 줄바꿈·빈칸까지 그대로 쓰게 하므로, main의 첫 줄부터 한 줄씩 내려가며 칸의 값과 찍힌 글자를 따라가야 합니다. 아래 그림은 한 줄이 실행될 때마다 칸에 값이 들고 출력이 쌓이는 모습입니다.
1C 프로그램의 뼈대
그림의 코드입니다.
#include <stdio.h>
int main(void) {
int score = 85;
char grade = 'B';
printf("%d ", score);
printf("%c\n", grade);
score = 90;
printf("score %d\n", score);
return 0;
}
85 B
score 90- 1번 줄
#include <stdio.h>는 printf가 선언된 헤더 파일을 불러옵니다. - 실행은 main의
{다음 첫 줄인 4번 줄부터 위에서 아래로 한 줄씩 합니다. - 문장은
;으로 끝나고, 중괄호{ }가 main의 몸을 묶습니다. - 10번 줄
return 0;에서 main이 끝납니다.
1번 줄의 헤더 파일, int main(void), return 0;은 지금은 늘 붙는 틀로 두고 넘어갑니다. main도 함수라서 함수 호출과 값·참조 전달에서 다시 봅니다.
2변수: 선언과 대입
선언(declaration)은 자료형과 이름을 적어 칸을 만드는 것이고, 대입(assignment)은 = 오른쪽 값을 왼쪽 칸에 넣는 것입니다.
int score = 85;처럼 선언하면서 값을 넣는 것을 초기화(initialization)라고 합니다.
칸에는 값이 하나만 듭니다. 8번 줄처럼 다시 넣으면 85는 남지 않습니다.
값을 넣지 않은 칸을 읽으면 무엇이 나올지 C가 정해 두지 않아서, 값을 먼저 넣고 읽습니다.
변수 이름에는 규칙이 있습니다. 예약어(reserved word)는 int·return처럼 C가 문법에 쓰려고 정해 둔 낱말이고, 키워드(keyword)라고도 부릅니다.
| 규칙 | 되는 이름 | 안 되는 이름 |
|---|---|---|
영문자·숫자·밑줄(_)만 쓴다 | score_2 | my-score · my score |
| 숫자로 시작하지 않는다 | score2 | 2score |
| 예약어를 쓰지 않는다 | integer | int · return |
| 대문자와 소문자를 가른다 | Score와 score는 다른 칸 | — |
3printf의 서식 지정자와 줄바꿈
printf의 첫 칸에 따옴표로 적은 글자를 서식 문자열(format string)이라 합니다. printf는 서식 문자열을 그대로 찍고, 그 안의 서식 지정자(format specifier) 자리에는 뒤에 적은 값을 차례로 넣어 찍습니다.
| 서식 지정자 | 찍는 것 | 예 → 찍히는 글자 |
|---|---|---|
%d | 정수 | printf("%d", 85) → 85 |
%c | 글자 하나 | printf("%c", 'B') → B |
%s | 문자열 | printf("%s", "pass") → pass |
printf는 줄을 저절로 바꾸지 않습니다. 6번 줄 끝에 \n이 없어 7번 줄의 B가 같은 줄에 이어 찍혔습니다.
\n처럼 역슬래시로 시작해 글자 하나를 나타내는 꼴을 이스케이프 시퀀스(escape sequence)라고 합니다. \t는 탭, \\는 역슬래시, \"는 큰따옴표입니다.
9번 줄 따옴표 안의 score는 변수가 아니라 글자라서 그대로 찍혔습니다.
예제
변수끼리 대입하는 줄과 \n이 없는 printf가 섞였습니다. 무엇이 찍힐까요?
#include <stdio.h>
int main(void) {
int a = 3;
int b = 5;
printf("%d", a);
a = b;
printf("%d\n", a);
printf("a=%d b=%d\n", a, b);
return 0;
}
실행 결과 보기
35
a=5 b=56번 줄 끝에 \n이 없어 3과 5가 한 줄에 붙습니다. 7번 줄 a = b;는 b의 값 5를 a 칸에 넣을 뿐이라 b는 5 그대로입니다.
같은 코드를 Java·Python으로
| C | Java | Python | |
|---|---|---|---|
| 찍는 줄 | printf("%d\n", a); | System.out.println(a); | print(a) |
| 줄바꿈 | \n이 있어야 바뀜 | println은 바꾸고 print는 안 바꿈 | 끝에서 바꾸고 end=''로 막음 |
| 변수 선언 | int a = 85; | int a = 85; | a = 85(자료형을 적지 않음) |
| 문장 끝 | ; | ; | 줄 끝 |
Python의 print는 끝에 줄바꿈을 붙입니다. end=''를 주면 붙이지 않아 다음 print가 같은 줄에 이어 찍습니다.
print('A', end='')
print('B')
print('C')
AB
C시험 포인트
- 필기: 변수 이름은 영문자·숫자·밑줄만 쓰고, 숫자로 시작하지 않으며, 예약어를 쓰지 않습니다. 대문자와 소문자는 다른 이름입니다. 서식 지정자
%d(정수)·%c(글자)·%s(문자열)와 줄바꿈\n을 묻습니다. - 실기: 출력을 줄바꿈·빈칸까지 그대로 씁니다. printf는
\n에서만 줄을 바꾸고, Python의 print는end=''가 없으면 끝에서 줄을 바꿉니다. 빈칸 채우기로 묻는 것은%d·%c·%s·\n과 print의 end입니다.
확인 문제
1. C에서 변수 이름으로 쓸 수 있는 것을 고르세요.
- ①
2nd - ②
my-score - ③
return - ④
_total2
정답
④입니다. 밑줄로 시작하고 영문자·숫자·밑줄만 썼습니다.
- ① 숫자로 시작해 이름이 될 수 없습니다.
- ②
-는 빼기 연산자라 my 빼기 score로 읽힙니다. - ③ return은 예약어입니다.
2. 위 예제에서 7번 줄만 b = a;로 바꿨습니다. 출력을 그대로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
정답
받는 답:
33
a=3 b=3
이번에는 a의 값 3이 b 칸에 들어가 둘 다 3입니다. 6번 줄 끝에 \n이 없어 3과 3이 한 줄에 붙습니다.
- 틀리는 꼴
35로 시작하는 답:=의 방향을 거꾸로 읽었습니다. 값은 오른쪽에서 왼쪽 칸으로 들어갑니다. - 틀리는 꼴 첫 줄을
3과3두 줄로 쓴 답: printf가 줄을 저절로 바꾼다고 봤습니다.
3. 다음 코드를 한 줄씩 따라가며 줄마다 칸의 값과 찍는 것을 적은 표(추적 표)의 (가)~(다)를 채운 뒤, 출력을 그대로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
#include <stdio.h>
int main(void) {
int x = 7;
char c = 'K';
printf("%c%d ", c, x);
x = 4;
printf("%d\n%s\n", x, "end");
return 0;
}
| 줄 | x | c | 그 줄이 찍는 것 |
|---|---|---|---|
| 4 | 7 | — | 없음 |
| 5 | 7 | K | 없음 |
| 6 | 7 | K | (가) |
| 7 | (나) | K | 없음 |
| 8 | 4 | K | (다) |
정답
(가) K · 7 · 빈칸 · (나) 4 · (다) 4 · 줄바꿈 · end · 줄바꿈
받는 답:
K7 4
end6번 줄은 %c에 K, %d에 7을 넣고 빈칸을 찍은 뒤 줄을 바꾸지 않습니다. 그래서 8번 줄의 4가 같은 줄에 붙고, 첫 \n 뒤에 end가 다음 줄에 찍힙니다.
- 틀리는 꼴
K7과4를 두 줄로 쓴 답: 6번 줄에\n이 없는 것을 놓쳤습니다. - 틀리는 꼴
K74: 6번 줄 서식 문자열 끝의 빈칸을 놓쳤습니다.
4. 다음 코드의 출력을 그대로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
#include <stdio.h>
int main(void) {
int n = 2;
int m = n;
char t = 'n';
n = 8;
printf("%c=%d ", t, n);
printf("m=%d\n", m);
printf("%s", "n");
printf("%d\n", n);
return 0;
}
정답
받는 답:
n=8 m=2
n85번 줄에서 m 칸에 2가 복사되고, 7번 줄이 n만 8로 바꿉니다. 'n'과 "n"은 따옴표 안 글자라 변수 n과 상관없이 n으로 찍힙니다.
- 틀리는 꼴
m=8: m이 n을 따라 바뀐다고 봤습니다. 5번 줄은 그때의 값 2를 복사할 뿐입니다. - 틀리는 꼴 둘째 줄
88: 따옴표 안 n을 변수로 읽었습니다.
5. 다음 (가)~(라)에 들어갈 것을 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
- (가)
printf("(가)", 85);가 85를 찍고 줄을 바꾸게 하는 서식 문자열 - (나)
printf("(나)", 'Q');가 Q 한 글자를 찍게 하는 서식 지정자 - (다)
printf("(다)", "ok");가 ok를 찍게 하는 서식 지정자 - (라) Python의
print(5, (라)='')가 줄을 바꾸지 않게 하는 이름
정답
받는 답: (가) %d\n · (나) %c · (다) %s · (라) end
(가)는 정수 자리 %d 뒤에 줄바꿈 \n을 붙입니다. (나)는 작은따옴표로 감싼 글자 하나, (다)는 큰따옴표로 감싼 문자열입니다. (라)는 print가 끝에 붙이는 글자를 정하는 이름입니다. printf에서 %i는 %d와 같아 (가)는 %i\n도 받습니다.
- 틀리는 꼴
%d— (가)에: 85는 찍지만 줄이 바뀌지 않습니다. printf는\n이 있어야 줄을 바꿉니다. - 틀리는 꼴
%d/n— (가)에: 줄바꿈은 빗금이 아니라 역슬래시로 씁니다. - 틀리는 꼴
%s— (나)에:%s는 큰따옴표로 감싼 문자열을 찍습니다. 글자 하나는%c입니다.
처음이라면: C 언어 과목(준비 중)의 '프로그램은 번역한 뒤 위에서 아래로' 레슨에서 같은 규칙을 처음부터 천천히 봅니다.