3강 · 제3장 · 65~77쪽 · 약 55분
입·출력 함수와 연산자(1)
함수의 개념을 짚고, 표준 출력함수(printf·putchar·puts)와 표준 입력함수(scanf·getchar·gets)를 예제로 익힙니다. (교재 제3장 65~77쪽)
학습 목표
- 함수(라이브러리 함수)가 이름·인자·반환값으로 호출되는 재사용 단위임을 설명한다
- 출력 양식이 문자형 상수 + 변환기호(%문자) + 제어문자(\문자)로 이루어짐을 설명한다
- 주요 변환기호(%d %ld %lld %u %o %x %f %e %c %s %%)를 자료형에 맞게 사용한다
- 표준 출력함수 printf·putchar·puts의 쓰임과 출력 양식 편집(%5d, %-5d, %05d, %7.2f)을 안다
- 표준 입력함수 scanf·getchar·gets의 쓰임과 주소 연산자 &, 공백 처리를 안다
- 교재 표기(void main, gets, #pragma warning, 출력의 %lf)와 이 사이트·표준 표기 차이를 안다
왜 이 강이 필요한가?
프로그램은 자료를 받아 처리하고 내보냅니다. 1·2강에서 변수와 자료형을 배웠으니, 이제 그 자료를 화면에 출력하고 키보드에서 입력하는 방법을 익힙니다.
이 강은 교재 제3장(입출력함수와 연산자) 의 65~77쪽 범위이며, 순서는 다음과 같습니다.
- 함수의 개념 — printf·scanf가 바로 “함수”입니다. 함수가 무엇인지부터 가볍게 정리합니다.
- 표준 출력함수 —
printf,putchar,puts - 표준 입력함수 —
scanf,getchar,gets
3장 후반의 연산자는 4강에서 다룹니다.
본문의 C 예제는 코드 아래에 실행 칸이 붙습니다. 다만 이 인라인 실행 칸에는 입력 상자가 없어서, scanf가 필요한 예제는 같은 변환 명세를 쓰는 sscanf(고정 문자열 파싱)로 결과를 보여 줍니다. 진짜 키보드 입력 실습은 맨 아래 종합 실습(입력 상자 있음)이나 상단 「코드연습」 탭에서 하세요.
1. 함수의 개념
함수(function) 는 어떤 일을 하는 코드에 이름을 붙여 두고, 필요할 때 그 이름으로 불러 쓰는(호출하는) 재사용 단위입니다. 수학의 y = f(x)처럼 생각하면 됩니다.
| 요소 | 설명 | printf("%d", n) 에서 |
|---|---|---|
| 이름 | 호출할 때 쓰는 식별자 | printf |
| 인자(argument) | 함수에 넘겨 주는 입력 값 | "%d", n |
| 반환값(return value) | 함수가 돌려주는 결과 값 | 출력한 문자 수(잘 안 씀) |
C가 제공하는 함수는 두 갈래입니다.
- 라이브러리 함수 — C 시스템이 미리 만들어 둔 함수.
printf,scanf,strlen등. 쓰려면 해당 헤더를#include합니다. - 사용자 정의 함수 — 내가 직접 만드는 함수. 6·7강에서 정의·호출·기억 클래스를 본격적으로 다룹니다.
C는 입출력을 언어 문법이 아니라 라이브러리 함수로 제공합니다. 그래서 모든 예제가 #include <stdio.h>로 시작합니다. #include는 함수의 선언(원형) 만 가져오고, 실제 구현은 링크 때 표준 라이브러리에서 연결됩니다(1강 복습).
이 예제 실행
실행 결과가 여기에 표시됩니다.
함수는 인자를 받아 일을 하고 값을 돌려줍니다. strlen("knou")는 길이 4를, printf("hello\n")는 출력한 문자 수 6을 반환합니다. 반환값을 꼭 쓸 필요는 없지만, “함수는 값을 돌려준다”는 감각을 잡아 두세요.
2. 표준 출력함수
자료를 컴퓨터 내부에 기억시키는 것을 입력, 내부에 기억된 내용을 외부(화면)로 나타내는 것을 출력이라고 합니다. C는 이 입출력을 언어 문법이 아니라 <stdio.h>의 라이브러리 함수로 제공하며, 대표 출력함수는 셋입니다.
| 함수 | 기능 |
|---|---|
printf() | 여러 종류의 자료를 양식을 지정해 출력 |
putchar() | 문자 1개를 출력 |
puts() | 문자열을 출력하고 자동으로 줄바꿈 |
2.1 printf — 양식 지정 출력
printf는 print formatted(양식을 지정한 출력), 뒤에 나오는 scanf는 scan formatted(양식을 지정한 입력)의 줄임말입니다.
- 형식:
printf("출력 양식", 인자1, 인자2, …); - 출력 양식(큰따옴표로 감쌈)은 세 가지로 이루어집니다.
- 문자형 상수 — 글자·숫자·기호. 그대로 화면에 나옴
- 변환기호
%문자— 뒤의 인자를 그 자리에 끼워 넣음 - 제어문자
\문자—\n(줄바꿈),\t(탭) 등 (2강 이스케이프 문자 복습)
인자는 왼쪽부터 순서대로 % 기호에 대응됩니다. 예를 들어 printf("A = %d, B = %c\n", a, b); 한 줄은 이렇게 나뉩니다.
printf("A = %d, B = %c\n", a, b); 의 조각 | 종류 | 하는 일 |
|---|---|---|
A = , , B = | 문자형 상수 | 그대로 화면에 출력 |
%d, %c | 변환기호 | a, b를 순서대로 그 자리에 끼워 넣음 |
\n | 제어문자 | 줄바꿈 |
이 예제 실행
실행 결과가 여기에 표시됩니다.
같은 변수 c가 %c(문자 A)와 %d(코드 값 65)에 각각 대응된 점을 보세요.
2.2 printf 변환기호
%문자 | 변환 형식 | 인자의 자료형 |
|---|---|---|
%d | 부호 있는 10진 정수 | char, short, int |
%ld / %lld | 10진 long / long long 정수 | long / long long |
%u | 부호 없는 10진 정수 | unsigned int |
%o | 부호 없는 8진수 | unsigned int |
%x, %X | 부호 없는 16진수 (소문자 / 대문자) | unsigned int |
%f | 10진 부동소수점 | float, double |
%e, %E | 지수 표기 | float, double |
%c | 문자 하나 | char, int |
%s | 문자열 | char * |
%p | 포인터 주소값 | void * |
%% | % 문자 자체 | (인자 없음) |
이 예제 실행
실행 결과가 여기에 표시됩니다.
- 같은 비트 패턴이라도
%u/%o/%x는 10진/8진/16진으로 다르게 보입니다. - 지수 결과는 이 사이트에서
1.234568e+03입니다. 교재(Windows)는 지수를 3자리로 써서1.234568e+003으로 나옵니다. 지수 자릿수는 환경마다 다릅니다.
생각해 보기:
printf("test", 123);처럼 인자가 남으면 남는 인자는 조용히 무시됩니다(정상 동작). 반대로printf("test %d");처럼 인자가 모자라면 쓰레기 값이 찍히거나 프로그램이 죽는 미정의 동작입니다. 컴파일러는-Wformat경고로 알려 줍니다.
2.3 printf 출력 양식 편집 — 폭·정렬·정밀도
%와 변환 문자 사이에 숫자·기호를 넣어 편집합니다.
| 편집 | 뜻 |
|---|---|
%5d | 최소 너비 5, 오른쪽 정렬(앞을 공백으로) |
%-5d | 최소 너비 5, 왼쪽 정렬(뒤를 공백으로) |
%05d | 최소 너비 5, 남는 앞자리를 0으로 채움 |
%6.1f | 전체 너비 6(소수점 포함), 소수 이하 1자리 |
%.11s | 문자열 앞 11자만 출력 |
이 예제 실행
실행 결과가 여기에 표시됩니다.
교재 예제3-1(종합) — \t 탭, %04d/%09d 0채움, %.3f/%.3e 정밀도, %.11s 자르기를 한 번에:
이 예제 실행
실행 결과가 여기에 표시됩니다.
2.4 putchar — 문자 1개 출력
- 형식:
putchar(문자);— 문자 하나를 출력합니다. - 인자는 정수형 변수·상수, 문자형 변수·상수, 수식이면 됩니다.
이 예제 실행
실행 결과가 여기에 표시됩니다.
putchar는 뒤에 나오는 입력함수 getchar와 짝입니다(문자 하나 출력 ↔ 문자 하나 입력).
2.5 puts — 문자열 출력
- 형식:
puts(변수);— 문자열을 출력한 뒤 자동으로 줄을 바꿉니다(문자열 끝\0을\n으로). - 그래서
printf("%s", s)와 달리\n을 따로 붙이지 않아도 됩니다. 반대로printf("%s", ...)를 연달아 쓰면 줄바꿈이 없어 붙어서 출력됩니다.
이 예제 실행
실행 결과가 여기에 표시됩니다.
3. 표준 입력함수
<stdio.h>가 제공하는 대표 입력함수도 셋이며, 출력함수와 하나씩 짝을 이룹니다.
| 함수 | 기능 | 짝이 되는 출력함수 |
|---|---|---|
scanf() | 양식을 지정해 1개 이상의 자료를 입력 | printf() |
getchar() | 문자 1개를 입력 | putchar() |
gets() | 문자열을 입력 (위험 — 3.3) | puts() |
3.1 scanf — 양식 지정 입력
- 형식:
scanf("입력 양식", &변수1, &변수2, …); - 변환기호는
printf와 거의 같지만double입력은%lf를 씁니다. (float은%f.)printf에서는 둘 다%f였습니다 — 여기서 갈립니다. - 모든 변수 앞에
&(주소 연산자). "값을 어디에 저장할지" 주소를 넘기는 것입니다. (포인터는 9강) - 문자열(배열명) 앞에는
&를 생략합니다. 배열명 자체가 주소이기 때문입니다. - 자료가 둘 이상이면 입력할 때 공백(스페이스·탭·엔터)으로 구분합니다.
%c앞에 공백 한 칸(" %c")을 두면, 앞선 입력에서 남은 엔터(\n)를 건너뜁니다.scanf가 실행되면 화면에 커서가 깜박이며 입력을 기다리고, 자료를 입력한 뒤 엔터를 누르면 전달됩니다.
scanf 입력 양식 변환기호 — printf의 변환기호를 거의 그대로 쓰지만, 실수는 자료형에 따라 갈립니다.
%문자 | 입력받는 자료 |
|---|---|
%d | 정수 (int) |
%ld / %lld | long / long long 정수 |
%f | 실수 (float) |
%lf | double 실수 |
%c | 문자 하나 |
%s | 공백 없는 문자열 |
%o / %x | 8진 / 16진 정수 |
인라인 실행 칸에는 입력 상자가 없으니, 문자열에서 읽는 sscanf로 같은 변환 명세를 연습합니다. (scanf의 키보드 대신 첫 인자의 문자열에서 읽을 뿐, 나머지는 동일합니다.)
이 예제 실행
실행 결과가 여기에 표시됩니다.
실제 키보드 입력 형식은 이렇게 씁니다(실행은 맨 아래 종합 실습·「코드연습」 탭에서):
int a;
long long b;
scanf("%d %lld", &a, &b); /* 예: 1234 1234567890 */
교재는
scanf를 쓰기 전에#pragma warning(disable:4996)를 넣습니다. 그건 Visual Studio 전용입니다. 이 사이트(GCC/clang)에서는 필요 없습니다.
3.2 getchar — 문자 1개 입력
- 형식:
ch = getchar();— 괄호 안에 인자가 없습니다. - 문자 하나를 읽어 정수(
int)로 반환합니다. 입력 끝(EOF)을 구분해야 하므로 저장 변수는int로 두는 것이 안전합니다. - 문자 입력 후 엔터를 눌러야 전달됩니다.
키보드로 받은 문자를 그대로 되돌려 찍는 예입니다(입력이 필요하므로 「코드연습」 탭에서):
int c;
while ((c = getchar()) != EOF)
putchar(c);
3.3 gets / fgets — 문자열 입력
- 교재 형식:
gets(변수);— 엔터까지(공백 포함) 한 줄을 읽어 배열에 저장하고 끝에\0을 붙입니다. - 문제: 입력 길이를 검사하지 않아 배열 크기를 넘겨 씁니다(버퍼 오버런).
gets는 C11 표준에서 삭제되었고, 최신 컴파일러는 경고하거나 아예 제공하지 않습니다. - 대안:
fgets(s, 크기, stdin)— 최대크기 - 1자만 읽어 안전합니다. (끝의 개행문자\n도 함께 저장될 수 있어, 필요하면 잘라냅니다.)
scanf("%s")와 gets/fgets의 결정적 차이는 공백 처리입니다. scanf("%s")는 공백에서 멈추고, 한 줄 전체를 읽지 못합니다.
이 예제 실행
실행 결과가 여기에 표시됩니다.
4. 교재 예제와 이 사이트가 다른 점
| 교재에서 자주 보임 | 이 사이트 | 이유 |
|---|---|---|
void main() | int main(void) | 표준 권장 형태 (1·2강과 동일) |
gets(s) | fgets(s, n, stdin) | gets는 C11에서 삭제·위험. 최신 컴파일러 미지원 |
scanf 앞 #pragma warning(disable:4996) | 불필요 | Visual Studio 전용 경고. GCC/clang은 그대로 컴파일 |
출력에 %lf | %f | 표준에서 printf는 float/double 모두 %f. %lf는 scanf의 double용 |
지수 %e → e+003 | e+03 | 지수 자릿수는 플랫폼마다 다름(Windows는 3자리) |
본문 예제에서 키보드 scanf | 본문은 sscanf로 결과 확인 | 인라인 실행 칸에 입력 상자가 없음. 실제 입력은 아래 종합 실습·「코드연습」 |
5. 지금 실습할 것
아래 종합 실습은 입력 상자가 있는 실행 칸입니다. 「표준 입력」 칸에 예: 25 3.5 K seoul 을 넣고 실행하세요. (비워 두면 기본값으로 동작합니다.)
- 그대로 실행해 각 변환기호(
%d %o %x %f %.2f %e %c %s) 결과 확인 %5d를%-5d,%05d로 바꿔 정렬·채움 비교%8.2f의 너비·정밀도 숫자를 바꿔 보기- 「표준 입력」의 마지막 값을
Computer Science로 바꿔%s가 공백에서 끊기는지 관찰 scanf의" %c"에서 앞 공백을 지우면grade에 무엇이 들어오는지 확인puts(city)와printf("%s", city)의 개행 차이 확인
printf 형식 요약: %d 정수, %ld/%lld long, %u/%o/%x 부호 없는 10·8·16진, %f/%.2f/%e 실수, %c 문자, %s 문자열, %%는 % 자체. scanf는 double에 %lf, 변수 앞에 &(문자열/배열명은 생략).
코드 실습 (C)
실행 결과가 여기에 표시됩니다.