chap4 2013 [호환 모드] · 2015. 5. 1. · microsoft powerpoint - chap4_2013 [호환 모드]...
TRANSCRIPT
1
Part 04입출력과전처리
2
전처리기지시자
전처리기(preprocessor) 컴파일러가 프로그램을 번역하기 '전'에 소스 프로그램을 '처리'하는 프로그램
전처리기 지시자(preprocessor directive) 전처리기에게 특정 작업을 지시하는 가짜 명령어(의사명령어) #으로 시작함
중요한 전처리기 지시자 #include: 다른 파일의 내용을 현재 파일에 포함시킴 #define: 특정 단어를 다른 문자열로 바꿈
#define을처리합니다.#include를처리합니다.
3
#include
파일 포함 지시자
헤더파일(header file) 다른 파일에 포함시킬 목적으로 작성된 파일
인클루드 파일(include file)이라고도 함헤더파일a.h
소스파일Source.c
전처리된소스파일
전처리기
4
헤더파일종류
<표준 헤더파일> 시스템의 특별한 위치에 존재
"일반 헤더파일" 소스파일과 같은 위치에서 찾을 수 있는 파일
5
변수 값출력프로그램
이부분을 별도의 헤더파일로 만들자
표준 헤더파일
실행결과:X = 101
// 전역변수
6
직접 작성한헤더파일 #include 예
일반헤더파일이므로 defineX.h는 include.c와 같은 디렉터리에있어야 함
실행결과:X = 101
7
#define
다른 문자열로 대치될 단어(매크로; macro)를 정의함
전처리기가 매크로 MESSAGE를"Have a nice day !"로 바꾸어준다 (확장된다. 그래서 macro라부른다).
실행결과:Have a nice day !
8
#define
9
매크로함수
함수 형태의 매크로 실제로 함수는 아니지만 함수와 같이 인수를 받는 형태로 macro정의
DUP("Hello? ")에서 MESSAGE는"Hello? "이므로 DUP("Hello? ")는 다음과 같이 바뀐다.
"Hello? " "Hello? "
문자열 리터럴을 나란히두면 컴파일러가 알아서접합한다.(실행결과와 같이)
실행결과:Hello? Hello?
10
매크로정의가길때
백슬래시(backslash)는 매크로 정의가 다음 줄에 계속됨을 의미함
실행결과:La La La La La La La La La La
11
요 약
전처리기 지시자 #include: 다른 파일을 포함시킴 #define: macro(다른 문자열로 바뀔 문구)를 정의함
macro 함수 macro를 이용하여 함수 형태로 정의한 것.
12
표준 라이브러리
라이브러리(library) 미리 작성해 둔 프로그램
표준 라이브러리(standard library) 컴퓨터 시스템이 달라도 같은 기능(same functionality)을 같은 방식(same interface)으로 사용할 수 있도록 작성해 둔 라이브러리
표준입출력 라이브러리(standard input/output library) 표준입출력을 다루는 프로그램(함수) 집합
Computer1,2의 하드웨어 instruction set들이 다르다. 그러나, 표준 library가있어 같은 C 프로그램으로 두 컴퓨터를 제어할 수 있다.
표준입출력(standard input/output):거의 모든 컴퓨터가 기본적으로 수행하는입출력으로 표준입력은 통상 키보드, 표준출력은 통상 모니터를 나타냄
13
printf: 모니터로출력하는출력함수
%d2
정수 i
"2"
문자열
%f3.14
실수 f
"3.140000"
문자열
%c'5'
문자 c
"5"
문자열
%로 시작하는printf (formatstring)은 데이터변환을 지시함
실행결과:i = 2f = 3.140000c = 5
14
printf포맷스트링
15
printf출력폭지정실행결과:i = 2f = 3.141593c = 5
10칸
format string에서 % 다음에 양의 정수를 기입하여출력 폭 지정
16
printf정밀도지정
실행결과:pi = 3.141593pi = 3.14pi = 3.141592653590
10칸
format string에서 %와 f 사이에 (출력폭이 지정된 경우, 출력폭 다음에) ".양수" 형태로 소수점 이하 자릿수 지정
3.1415926535897
12자리
반올림
형식지정자 의미
%6.4d
%6.2f
6자리중에서 4자리로출력
전체폭은 6, 소수점이하자리 2, 우축정렬 1 . 2 3
0 1 2 3
17
scanf:형식에맞는입력함수
%d 27
정수 n
"27"
문자열
Scanf의 format string은 문자열을데이터로 변환함
실행결과:27entered n = 27double of n = 54triple of n = 81
주소연산자 &를 사용한 점에 주의!
18
scanf의주소연산자
주소 연산자(address-of operator) &: 변수의 주소를 계산하는 연산자
scanf("%d", &n);
표준입력에서 변환한 값을 저장할 장소를 알아야 하기 때문에 변수 n의 주소(&n)를 두 번째 인수로 사용함 &변수: 해당 변수가 할당된 메모리 주소
주소 연산자를 누락시키면 실행시간오류
(변수에 값을 저장하려면변수의 주소가 필요)
19
프롬프트 (prompt)
프롬프트(prompt) 입력할 내용을 설명해 주는 안내문
프롬프트가 없으면 "프로그램이 죽은" 것으로 오해할 수 있음 앞 슬라이드의 프로그램은 프롬프트가 없다!
사실 깜빡이는 형태의 빈(null) 프롬프트가 존재
20
scanf:프롬프트를사용한버전
실행결과:정수 n을 입력해 주세요. n = 27입력한 n = 27n의 두 배 = 54n의 세 배 = 81
바로 이것이 prompt!입력할 내용을 설명해준다.
scanf:입력할자료의자릿수
함수 scanf( )는 printf( )와 같이 입력할 숫자의 자릿수를지정할 수도 있다.
21
1 //******************************************2 //3 // 입력할 정수 숫자의 자릿수를 지정하여 입력.4 //******************************************56 #include <stdio.h>78 int main()9 {10 int num;1112 printf("정수 4자리 입력 후 Enter>");13 scanf("%4d", &num);14 printf("입력한 된 정수 : %d\n", num);15 }
실행결과:정수 4자리 입력후 Enter> 4253입력한 정수 : 4253
22
scanf포맷스트링
TIP:double 타입으로 입력 받아야 할 경우에는 %f 대신 %lf를 사용한다.
#include <stdio.h>int main(){
double n = 0;
scanf("%lf", &n);printf("entered n = %f\n",n);return 0;
}
23
getchar, putchar: 문자입출력함수
실행결과:소문자를 입력하세요. aa의 대문자는 A입니다.
안내문구(prompt)
getchar 'a'
문자
a.....
표준입력(KB)
putchar'A'
문자
.....A
표준출력(Monitor)
putchar가 출력한 문자들
대문자로 변환하는함수 toupper()
24
gets, puts: 줄단위입출력함수
실행결과:
사용자가 입력한 \n
puts가 출력한 \n
line에는 여기까지만저장됨(\n은 제외됨)
// 배열
25
gets, puts: 개행문자처리
개행문자 처리 gets는 \n을 떼고 \0(null 문자)을 붙여 준다. puts는 \n을 문자열 출력 끝에 자동으로 붙여 준다.
이전 예에서 gets 처리 후 line[256] 상황
(배열은 Ch. 9&10에서 설명!)
26
입력 버퍼 실행결과:정수 n과 문자 c를 입력해 주세요.250 an = 250c =
a는 어디로?
c에는 공백문자가저장됨
printf(“정수 n과문자 c를입력해주세요.\n”);
(scanf는 읽기표식이 나타내는위치부터 읽기 시작함.)
수정scanf("█%c", &c);
27
입력 버퍼
%c와 %c 사이에공백이있으면, 입력시문자사이에공백이있어도되고없어도됨.
x y 도가능함
주의: %c와 %c 사이에공백이없으면, 입력시문자사이에공백이없어야함.
x y 만가능함
28
scanf가공백을건너뛰는습성
포맷 스트링 %c의 특이함 포맷 스트링 %c는 공백을 건너뛰지 않음(공백도 문자로 생각함!) 포맷 스트링에 공백이 하나라도 있으면 여러 공백문자에 대응함
scanf("%d%c", …) ≠ scanf("%d %c", …) 포맷 스트링 %c를 제외하고는 모두 공백을 건너뜀
scanf("%d%d", …) ≡ scanf("%d %d", …)
%s로도 공백을 건너뛰어 문자를 읽을 수 있다 %s(항상 공백문자를 건너뜀)로 입력을 받되 입력 폭을 1로 지정
char c;
scanf("% 1s", &c); // scanf("█%c", &c);와 같음
%s로 공백을 건너뛰지 않으려면? 불가능함. gets를 사용하세요!
29
입력 버퍼
printf(“정수 n과문자 c를입력해주세요.\n”);
수정scanf("█%c", &c);
수정scanf("%d█%c", &n,&c);
scanf("%d%1s", &n,&c);
또는
30
입출력방향재지정
입력 재지정(input redirection) 표준입력 대신 파일로부터 입력 받음
program.exe < inputFile.txt
출력 재지정(output redirection) 표준출력 대신 파일로 내용을 저장
program.exe > outputFile.txt
합쳐서… program.exe < inputFile.txt > outputFile.txt
program.exe > outputFile.txt < inputFile.txt
<를 로, >를 로 생각하면 기억하기 쉽다.
31
입출력방향재지정
예: getsput.c를 실행하여 getsput.exe 생성.
input.txt 파일을 아래와 같이 작성한다.
Win32 console에서 getsput.exe < input.txt 을 실행한다.
실행 결과:
This is a sample input.
한 라인을 입력해주세요.
입력하신 라인은 다음과 같습니다.This is a sample input.
32
전처리기지시자복습
매크로 정의가 길 경우에는 행 끝에 \를 넣어 다음 줄에계속 정의한다.
33
매크로함수의한계?
실행결과:x = 250x = 747
이 x를 y로 바꾸고 싶지 않습니까?
printf("x=%d\n",x);
printf("x=%d\n",y);
34
매크로인수연산 #x
실행결과:x = 250y = 747
# 하나만 넣었을 뿐인데…
PR(y)printf(#y " = %d\n", y)printf("y" " = %d\n", y)printf("y = %d\n", y)
매크로 인수 x를 문자열로 바꿈
35
매크로인수연산 ##
매크로 인수 연산자 ## 매크로 인수 이름을 붙여 줌
문자열을 붙이는 것이 아니라 인수 이름 자체를 붙임
## 사용 예#define MERGE(x, y) x ## y
...
MERGE(x, 1) = 25;
// x1 = 25; 로 확장됨
MERGE(blue, berry) *= MERGE(x, 1);
// blueberry *= x1; 으로 확장됨
...
36
Key Point 1
전처리기 지시자 #include: 다른 파일을 포함시킴 #define: 매크로(다른 문자열로 바뀔 문구)를 정의함
표준입출력 키보드(std. in)와 모니터(std. out)를 추상화함 문자 단위 입출력을 수행함
표준입출력 라이브러리 형식에 따른 입출력: printf(), scanf() 문자 단위 입출력: getchar(), putchar() 줄 단위 입출력: gets(), puts()
37
Key Point 2
버퍼 입출력 속도 차이를 메워주기 위한 임시 저장소
버퍼오버런: 저장 범위를 넘어 다른 영역에 침범하는 현상
입출력 방향 재지정 표준입출력 대신 파일을 사용하도록 지정함
매크로 인수 활용 #x: 매크로 인수 x에 해당하는 문자열
x ## y: 매크로 인수 이름 x와 y를 접합함
38
주의사항 Key Point
사용자로부터 입력 받을 때에는 안내문구(prompt)를 사용하는 것이 좋음
scanf의 인수로는 변수의 주소를 주어야 함int x;
scanf("%d", x); // 잘못됨
scanf("%d", &x); // 올바름
scanf로 double형 데이터를 읽으려면 "%lf"를 이용함
scanf 포맷 스트링 "%c"는 공백을 건너뛰지 않음 " %c"를 이용하거나
"%1s"를 이용함