39
12. 고급 기능 1 #include <stdio.h> int main(void) { int num; printf(“Please enter an integer: "); scanf("%d", &num); if ( num < 0 ) printf("Is negative.\n"); printf("num = %d\n", num); return 0; } ■ 전처리기가 제공하는 매크로 상수와 매크로 함수 기능에 대하여 알아본다. ■ 전처리기가 제공하는 매크로 상수와 매크로 함수 기능에 대하여 알아본다. ■ 전처리기가 제공하는 조건부 컴파일 기능에 대하여 알아본다. ■ 전처리기가 제공하는 조건부 컴파일 기능에 대하여 알아본다. ■ 프로그램의 여러 개의 소스 파일로 나누어 작성하는 분할 컴파일을 하기 위한 방법에 대하여 알아본다. ■ 프로그램의 여러 개의 소스 파일로 나누어 작성하는 분할 컴파일을 하기 위한 방법에 대하여 알아본다. main 함수의 매개변수에 대하여 알아본다. main 함수의 매개변수에 대하여 알아본다. 12장. 고급 기능 학습목표 2

12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

12장. 고급 기능

1

#include <stdio.h>int main(void){

int num;printf(“Please enter an integer: ");scanf("%d", &num);if ( num < 0 )

printf("Is negative.\n");printf("num = %d\n", num);return 0;

}

■ 전처리기가 제공하는 매크로 상수와 매크로 함수 기능에 대하여 알아본다.■ 전처리기가 제공하는 매크로 상수와 매크로 함수 기능에 대하여 알아본다.

■ 전처리기가 제공하는 조건부 컴파일 기능에 대하여 알아본다.■ 전처리기가 제공하는 조건부 컴파일 기능에 대하여 알아본다.

■ 프로그램의 여러 개의 소스 파일로 나누어 작성하는 분할 컴파일을 하기

위한 방법에 대하여 알아본다.

■ 프로그램의 여러 개의 소스 파일로 나누어 작성하는 분할 컴파일을 하기

위한 방법에 대하여 알아본다.

■ main 함수의 매개변수에 대하여 알아본다.■ main 함수의 매개변수에 대하여 알아본다.

12장. 고급 기능

학습목표

2

Page 2: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

12장. 고급 기능

목차

3

전처리기

• 매크로

• 조건부 컴파일

전처리기

• 매크로

• 조건부 컴파일

분할 컴파일

• #include• 헤더 파일과 소스 파일• 헤더 파일의 중복 문제• 헤더 파일과 소스 파일의 구성

분할 컴파일

• #include• 헤더 파일과 소스 파일• 헤더 파일의 중복 문제• 헤더 파일과 소스 파일의 구성

main 함수의 매개변수

• main 함수의 원형

• main 함수의 매개변수

main 함수의 매개변수

• main 함수의 원형

• main 함수의 매개변수

전처리기(1/2)컴파일러가 소스 파일을 컴파일하기 전에 먼저 수행되는 프로그램프로그래머가 작성한 소스 파일이 컴파일될 수 있도록 준비한다.전처리기 문장은 ‘#’으로 시작한다.

12장. 고급 기능

전처리기

4

Page 3: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

전처리기(2/2)

12장. 고급 기능

전처리기

5

매크로 상수(1/2)

전처리기는 소스 파일에서 매크로 상수가 사용된 곳을 모두 찾아서 정의된 문자열로 대치한다.

12장. 고급 기능

매크로

전처리기

6

Page 4: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

매크로 상수(2/2)정수형 상수, 실수형 상수나 문자열 상수도 매크로 상수로 정의할 수 있으며, 함수명이나 데이터형도 매크로 상수로 정의할 수 있다.

12장. 고급 기능

매크로

전처리기

7

매크로 함수(1/3)매크로 함수는 함수처럼 인자를 갖는 매크로이다. 매크로 상수처럼 매크로 함수가 사용되는 곳에 문자열 대치를 통해서 코드를 확장한다.

12장. 고급 기능

매크로

전처리기

8

Page 5: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

매크로 함수(2/3)

전처리기는 프로그램에서 매크로 함수가 사용된 곳을 만나면 ( ) 안에 있는 문자열을 매크로 함수의 인자에 매핑해서, 문자열 대치를 수행한다.

12장. 고급 기능

매크로

전처리기

9

매크로 함수(3/3)매크로 함수는 함수인 것처럼 보이지만 사실은 함수가 아니다.컴파일시에 인자의 데이터형 검사를 수행하지 않으며, 인자를 매개변수로 전달하는 함수 호출 과정이 수행되지 않는다.매크로 함수 사용 시 문자열 대치 과정에서 잘못된 결과가 만들어질 수도 있다.

12장. 고급 기능

매크로

전처리기

10

Page 6: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

매크로 함수를 정의하고 사용하는 예(1/3)

12장. 고급 기능

매크로

전처리기

11

01: /* Ex12_01.c */02: #include <stdio.h>03:04: #define SQUARE(n) n*n05:06: int square(int n)07: {08: return n*n;09: }10:11: int main(void)12: {13: int result = SQUARE(3); 14: printf("3의 제곱 : %d\n", result);15:16: result = SQUARE(1+2);17: printf("SQUARE(1+2) = %d\n", result);18:

매크로함수의정의

매크로함수의호출

매크로함수의호출

매크로 함수를 정의하고 사용하는 예(2/3)

12장. 고급 기능

매크로

전처리기

12

19: result = square(1+2); 20: printf("square(1+2) = %d\n", result);21:22: printf("SQUARE(2.5) = %f\n", SQUARE(2.5)); 23: printf("square(2.5) = %d\n", square(2.5)); 24:25: return 0;26: }

일반함수의호출

매크로함수의호출

일반함수의호출

Page 7: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

매크로 함수 사용 시 주의사항(1/2)일반 함수는 먼저 인자의 값을 계산한 다음에 함수가 호출된다.매크로 함수는 문자열 대치로 처리되므로 인자의 값을 먼저 계산하지 않는다.매크로 함수의 인자를 사용할 때 ( )로 묶어주어야 한다.

매크로 함수의 인자로 증감연산자를 이용한 연산식을 사용하지 않도록 주의해야한다.

12장. 고급 기능

매크로

전처리기

13

매크로 함수 사용 시 주의사항(2/2)매크로 함수는 인자의 데이터형을 검사하지 않는다.

여러 줄로 된 매크로함수를 정의하려면 각 라인의 맨 끝에 \을 써주어야 한다.

12장. 고급 기능

매크로

전처리기

14

Page 8: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

매크로 함수의 장단점장점 : 매크로 함수를 사용하면 프로그램의 실행 속도가 빨라진다.

매크로 함수를 사용할 때는 함수 호출이 일어나지 않으므로 함수 호출의 오버헤드를줄일 수 있다.

단점 : 매크로 함수를 많이 사용하는 프로그램은 프로그램의 크기가 커진다.일반 함수 코드는 한 번만 컴파일해서 만들어두고, 함수 코드를 필요할 때마다 반복해서 호출한다.매크로 함수는 사용되는 곳마다 매크로 함수를 확장한 코드가 복사된다.

매크로 함수를 사용하면, 코드가 알아보기 어려워진다.매크로 함수를 이용하면 일반 함수로는 구현할 수 없는 기능도 처리할 수 있기 때문에 라이브러리나 복잡한 프로그램에서 자주 사용된다.

12장. 고급 기능

매크로

전처리기

15

전처리기 연산자 #문자열 만들기 연산자(stringizing operator)# 다음에 오는 매크로 함수의 인자를 “ ”로 묶어서 문자열 리터럴로 만든다.

12장. 고급 기능

매크로

전처리기

16

Page 9: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

전처리기 연산자 ##토큰 결합 연산자(token-pasting operator)매크로 함수 안에서 토큰에 다른 토큰을 결합해서 새로운 토큰을 생성한다.

12장. 고급 기능

매크로

전처리기

17

# 연산자와 ## 연산자 사용 예(1/2)

12장. 고급 기능

매크로

전처리기

18

01: /* Ex12_02.c */02: #include <stdio.h>03:04: #define PRINT1(x) printf("x = %d\n", x)05: #define PRINT2(x) printf(#x" = %d\n", x)06:07: #define MAKE_FUNC(name) void fn##name(void) \08: { \09: printf("fn"#name" 호출\n"); \10: }11:12: MAKE_FUNC(test1, 1)13: MAKE_FUNC(test2, 2)14:15: int main(void)16: {17: int num = 10;18: PRINT1(num);19: PRINT2(num);

매크로함수의정의

#을이용한매크로함수의정의

#과 ##을이용한매크로함수의정의

Page 10: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

# 연산자와 ## 연산자 사용 예(2/2)

12장. 고급 기능

매크로

전처리기

19

20:21: fntest1( );22: fntest2( );23:24: return 0;25: }

조건부 컴파일특정 조건이 만족할 때만 코드를 컴파일한다.상황에 따라서 특정 코드를 컴파일하게 또는 컴파일하지 않게 만들 수 있다. 이식성 있는 코드를 개발할 때 유용하다.

12장. 고급 기능

조건부 컴파일

전처리기

20

Page 11: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

#if, #else, #endif(1/3)

#if의 조건식에는 매크로를 정수와 비교하는 관계 연산자가 주로 사용되고, 산술연산자, 논리 연산자 등이 사용될 수 있다.

12장. 고급 기능

조건부 컴파일

전처리기

21

#if, #else, #endif(2/3)#if의 조건식에서 매크로를 실수나 문자열과 비교할 수 없다.

#if에는 반드시 짝이 되는 #endif가 필요하며, #else를 함께 사용할 수도 있다.

조건이 참이면 문장1을 컴파일하고, 조건1이 거짓이면 문장2를 컴파일한다. #else문에 다른 조건을 다시 검사하려면 #elif를 사용한다.

12장. 고급 기능

조건부 컴파일

전처리기

22

Page 12: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

#if, #else, #endif(3/3)#if, #endif 에서는 컴파일할 문장이 여러 개여도 { }로 묶어줄 필요가 없다.

#if 안에 다른 #if를 중첩해서 사용할 수 있으며, 각각의 #if마다 #endif가 하나씩짝을 이루어야 한다.

12장. 고급 기능

조건부 컴파일

전처리기

23

#ifdef(1/3)“if defined”라는 의미이다.#ifdef는 특정 매크로의 정의 여부에 따라 #ifdef와 #endif 사이의 문장을 컴파일할지 결정한다.

12장. 고급 기능

조건부 컴파일

전처리기

24

Page 13: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

#ifdef(2/3)DEBUG 매크로 정의시 에만 함수 정보를 출력하는 경우

출력문에 수행되려면 DEBUG 매크로 정의가 필요하다.

12장. 고급 기능

조건부 컴파일

전처리기

25

#ifdef(3/3)

12장. 고급 기능

조건부 컴파일

전처리기

26

Page 14: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

#ifdef를 이용한 디버깅 정보 출력(1/2)

12장. 고급 기능

조건부 컴파일

전처리기

27

01: /* Ex12_03.c */02: #include <stdio.h>03:04: #define DEBUG DEBUG05:06: int GetFactorial(int n);07:08: int main(void)09: {10: int result;11:12: result = GetFactorial(5);13:14: printf("result = %d\n", result);15:16: return 0;17: }18:

매크로심볼의정의

#ifdef를 이용한 디버깅 정보 출력(2/2)

12장. 고급 기능

조건부 컴파일

전처리기

28

19: int GetFactorial(int n)20: {21: #ifdef DEBUG22: printf("GetFactorial 함수 호출 : ");23: printf("n = %d\n", n);24: #endif25:26: if( n <= 1 )27: return 1;28: return n * GetFactorial(n - 1);29: }

조건부컴파일

Page 15: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

#ifndef“if not defined”라는 의미이다.#ifnded 다음의 매크로가 정의되지 않은 경우에만 #ifndef와 #endif 사이의 문장이 컴파일된다.

#ifdef나 #ifdef에서 사용되는 매크로 심볼의 정의#define을 이용하거나 C 컴파일러의 컴파일러 스위치를 이용해서 정의한다.

12장. 고급 기능

조건부 컴파일

전처리기

29

분할 컴파일의 필요성작성해야 할 코드의 양이 많거나 여러 사람이 공동 개발을 해야 하는 경우에는 소스 파일을 여러 개로 나누어서 프로그램을 개발해야 한다.

관련된 함수나 변수들끼리 한 파일로 모아서 작성한다. 관련된 코드를 한 곳에 모아두면 유지 보수하기가 쉬워진다.

헤더 파일서로 다른 소스 파일 사이에서 필요한 정보를 공유할 수 있게 만들어 준다.파일 확장자로 .h를 사용한다.소스 파일에 정의된 함수나 전역 변수를 사용하는 데 필요한 정보를 제공한다.소스 파일에 헤더 파일을 포함하려면 #include를 이용한다.

12장. 고급 기능

분할 컴파일

30

Page 16: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

헤더 파일과 소스 파일

12장. 고급 기능

분할 컴파일

31

#include문헤더 파일은 전처리기 문장인 #include에 의해서 소스 파일 안에 포함된 후 컴파일된다. 전처리기는 #include가 지정한 헤더 파일의 내용을 #include가 사용된 위치로 복사해 넣어준다.

12장. 고급 기능

#include

분할 컴파일

32

Page 17: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

#include <라이브러리 헤더>전처리기는 헤더 파일을 C 컴파일러의 포함 경로(include path)에서 찾는다. 포함 경로는 컴파일러가 제공하는 표준 라이브러리의 헤더 파일이 모여 있는 디렉터리이다.

#include “사용자 정의 헤더”전처리기는 헤더 파일을 소스 파일이 있는 디렉터리에서 찾는다.

12장. 고급 기능

#include

분할 컴파일

33

헤더 파일의 경로명<>나 “” 안에 헤더 파일의 완전 경로명이나 상대 경로명을 지정할 수도 있다.

12장. 고급 기능

#include

분할 컴파일

34

Page 18: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

다른 파일에 정의된 함수의 호출(1/7)C 컴파일러는 각각의 소스 파일마다 독립적으로 컴파일을 수행한다.함수 호출 시 함수의 선언이나 정의가 없으면 컴파일 경고가 발생한다.

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

35

다른 파일에 정의된 함수의 호출(2/7)다른 파일에 정의된 함수를 호출하려면 함수의 선언이 필요하다.

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

36

Page 19: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

다른 파일에 정의된 함수의 호출(3/7)소스 파일이 여러 개면 소스 파일마다 함수의 선언이 필요하다.

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

37

다른 파일에 정의된 함수의 호출(4/7)헤더 파일을 이용하면 함수 선언을 한 곳에 모아둘 수 있다.

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

38

Page 20: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

다른 파일에 정의된 함수의 호출(5/7)소스 파일의 이름을 따서 헤더 파일을 만든다.

Array.c에 정의된 함수들을 다른 소스 파일에서 호출할 수 있게 하려면 먼저 Array.c의이름을 따서 Array.h를 만든다.

헤더 파일에 함수의 선언을 넣어준다.함수를 호출하려면 소스 파일마다 헤더 파일을 포함한다.

Array.c에 정의된 함수를 호출하려고 하는 소스 파일마다 #include를 이용해서 Array.h을 포함한다.

특정 소스 파일에 대한 헤더 파일을 만들고 나면, 소스 파일에도 자기 자신의 헤더 파일을 포함해주는 것이 좋다.

Array.c에도 Array.h를 포함해준다.

소스 파일은 각각 독립적으로 컴파일되므로, 라이브러리 헤더는 라이브러리를 사용하는 소스 파일마다 각각 포함해주어야 한다.

입출력 라이브러리를 사용하는 소스 파일마다 <stdio.h>를 포함해야 한다.

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

39

다른 파일에 정의된 함수의 호출(6/7)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

40

Page 21: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

다른 파일에 정의된 함수의 호출(7/7)① 먼저 호출될 함수의 정의가 들어있는 소스 파일의 이름을 따서 헤더 파일을 생성

한다.② 헤더 파일에는 다른 소스 파일에서 호출될 함수의 선언을 넣어준다.③ 다른 소스 파일에서 해당 함수를 호출하려면 함수 선언이 들어있는 헤더 파일을

포함하고 사용한다.

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

41

다른 파일에 정의된 함수의 호출 예(1/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

42

01: /* Array.h */02: void PrintArray(const int *arr, int size);03: int GetSumOfArray(int *arr, int size);04: void SortArray(int *arr, int size);

함수의선언

Array.h

01: /* Array.c */02: #include <stdio.h>03: #include "Array.h"04:05: void PrintArray(const int *arr, int size)06: {07: int i;08:09: //arr[0] = 100;10: for(i = 0 ; i < size ; i++)11: printf("%d ", arr[i]);

라이브러리헤더파일포함

Array.c

자기자신의헤더파일포함

Page 22: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

다른 파일에 정의된 함수의 호출 예(2/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

43

12: printf("\n");13: }14:15: int GetSumOfArray(int *arr, int size)16: {17: int i;18: int total;19:20: for(i = 0, total = 0 ; i < size ; i++)21: total += arr[i];22:23: return total;24: }25:26: void SortArray(int *arr, int size)27: {28: int i, j, index;29: int temp;

Array.c(continued)

다른 파일에 정의된 함수의 호출 예(3/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

44

31: for(i = 0; i < size-1 ; i++)32: {33: index = i;34: for( j = i+1 ; j < size ; j++)35: {36: if( arr[index] > arr[ j] )37: index = j;38: }39: temp = arr[i];40: arr[i] = arr[index];41: arr[index] = temp;42: }43: }

Array.c(continued)

Page 23: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

다른 파일에 정의된 함수의 호출 예(4/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

45

01: /* Main.c */02: #include <stdio.h>03: #include "Array.h"04:05: int main(void)06: {07: int x[5] = {43, 6, 24, 88, 34};08: int y[10] = {12, 35, 7, 45, 78, 22, 98, 77, 1, 28};09:10: printf("x 배열 : ");11: PrintArray(x, 5);12: printf("합계 : %d\n\n", GetSumOfArray(x, 5));13:14: printf("y 배열 : ");15: PrintArray(y, 10);16: SortArray(y, 10);

Main.c

라이브러리헤더파일포함

사용자정의헤더파일포함

다른 파일에 정의된 함수의 호출 예(5/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

46

17: printf("정렬후 : ");18: PrintArray(y, 10);19:20: return 0;21: }

Main.c(continued)

Page 24: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

매크로, 구조체, typedef의 공유매크로나 구조체, typedef는 소스 파일마다 정의가 필요하므로 매크로, 구조체, typedef의 정의를 헤더 파일에 넣어준다.

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

47

여러 소스 파일에서 공유되는 매크로나 구조체, typedef의 정의① 매크로, 구조체, typedef의 정의는 소스 파일마다 필요하므로 헤더 파일에 넣어

준다.② 헤더 파일에 구조체나 typedef를 사용하는 함수 선언이 들어갈 때는, 구조체나

typedef 정의 다음에 함수 선언을 넣어준다.③ 매크로, 구조체, typedef를 사용하는 소스 파일마다 헤더 파일을 포함한다.

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

48

Page 25: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

여러 소스 파일에 사용되는 구조체의 정의 예(1/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

49

01: /* Point.h */02: struct point {03: int x;04: int y;05: };06: typedef struct point POINT; 07:08: void PrintPoint(const POINT *p);09: void MovePoint(POINT *p, int dx, int dy);10: double GetDistance(const POINT *p1, const POINT *p2);

구조체의정의

Pont.h

구조체에대한 typedef정의

구조체를매개변수로갖는함수의선언

여러 소스 파일에 사용되는 구조체의 정의 예(2/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

50

01: /* Point.c */02: #include <stdio.h>03: #include <math.h>04: #include "Point.h"05:06: void PrintPoint(const POINT *p)07: {08: printf("(%d, %d)\n", p->x, p->y);09: }10: void MovePoint(POINT *p, int dx, int dy)11: {12: p->x += dx;13: p->y += dy;14: }15:

Pont.c

사용자정의헤더파일포함

라이브러리헤더파일포함

Page 26: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

여러 소스 파일에 사용되는 구조체의 정의 예(3/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

51

16: double GetDistance(const POINT *p1, const POINT *p2)17: {18: int dx = p2->x - p1->x;19: int dy = p2->y - p1->y;20: return sqrt(dx*dx+dy*dy);21: }

Pont.c(continued)

01: /* Main.c */02: #include <stdio.h>03: #include "Point.h"04:05: int main(void)06: {07: POINT p1 = {0, 0};08: POINT p2 = {300, 400};09:

Main.c

라이브러리헤더파일포함

사용자정의헤더파일포함

여러 소스 파일에 사용되는 구조체의 정의 예(3/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

52

10: printf("p1 = ");11: PrintPoint(&p1);12: printf("p2 = ");13: PrintPoint(&p2);14:15: printf("두 점 사이의 거리 : %f\n", GetDistance(&p1, &p2));16:17: MovePoint(&p2, 10, 10);18: printf("MovePoint 호출 후 p2 = ");19: PrintPoint(&p2);20:21: return 0;22: }

Main.c(continued)

Page 27: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

헤더 파일의 순서헤더 파일 안에 구조체의 정의와 함수 선언을 함께 넣어줄 때는 순서에 주의해야한다.

point 구조체와 typedef를 함수 선언보다 앞쪽에 정의할 때는 올바르게 컴파일이 되지만, 함수 선언보다 뒤쪽에 정의하면 컴파일 에러가 발생한다.

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

53

다른 소스 파일에 선언된 전역 변수의 사용(1/2)다른 소스 파일에 선언된 전역 변수를 사용하려면 전역 변수의 extern 선언을 헤더 파일에 넣어준다.

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

54

Page 28: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

다른 소스 파일에 선언된 전역 변수의 사용(2/2)① 전역 변수는 프로그램 전체에서 반드시 하나의 소스 파일에 선언한다. 즉, 하나의

소스 파일에서만 메모리가 할당되어야 한다.② 전역 변수가 선언된 소스 파일의 헤더 파일에 전역 변수에 대한 extern 선언을

넣어준다. 전역 변수의 extern 선언은 메모리를 할당하지 않고, 전역 변수의 데이터형과 변수명만 알려준다.

③ 전역 변수를 사용하려면 전역 변수의 extern 선언이 들어있는 헤더 파일을 포함한다.

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

55

다른 소스 파일에 정의된 전역 변수의 사용 예(1/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

56

01: /* Point.h */02: struct point {03: int x;04: int y;05: };06: typedef struct point POINT; 07:08: void PrintPoint(const POINT *p);09: void MovePoint(POINT *p, int dx, int dy);10: double GetDistance(const POINT *p1, const POINT *p2);11: void SetOrigin(int x, int y);12:13: extern POINT g_origin;

Pont.h

전역변수의 extern 선언

Page 29: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

다른 소스 파일에 정의된 전역 변수의 사용 예(2/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

57

01: /* Point.c */02: #include <stdio.h>03: #include <math.h>04: #include "Point.h"05:06: POINT g_origin; 07:08: void PrintPoint(const POINT *p)09: {10: printf("(%d, %d)\n", p->x, p->y);11: }12:13: void MovePoint(POINT *p, int dx, int dy)14: {15: p->x += dx;16: p->y += dy;17: }

Pont.c

전역변수선언

다른 소스 파일에 정의된 전역 변수의 사용 예(3/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

58

18:19: double GetDistance(const POINT *p1, const POINT *p2)20: {21: int dx = p2->x - p1->x;22: int dy = p2->y - p1->y;23: return sqrt(dx*dx+dy*dy);24: }25:26: void SetOrigin(int x, int y)27: {28: g_origin.x = x;29: g_origin.y = y;30: }

Pont.c(continued)

전역변수의사용

Page 30: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

다른 소스 파일에 정의된 전역 변수의 사용 예(4/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

59

01: /* Main.c */02: #include <stdio.h>03: #include "Point.h"04:05: int main(void)06: {07: POINT p1 = {100, 200};08: POINT p2 = {300, 400};09:10: printf("p1 = ");11: PrintPoint(&p1);12: printf("p2 = ");13: PrintPoint(&p2);14:15: printf("두 점 사이의 거리 : %f\n", GetDistance(&p1, &p2));16:

Main.c

사용자정의헤더파일포함

다른 소스 파일에 정의된 전역 변수의 사용 예(5/5)

12장. 고급 기능

헤더 파일과 소스 파일

분할 컴파일

60

17: printf("원점과 p2 사이의 거리 : %f\n",18: GetDistance(&g_origin, &p2));19:20: return 0;21: }

Main.c(continued)

Page 31: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

소스 파일에 같은 헤더 파일이 여러 번 포함되서는 안된다.

12장. 고급 기능

헤더 파일의 중복 문제

분할 컴파일

61

헤더 파일의 중복 피하기(1/2)헤더 파일의 시작과 끝에 #ifndef, #define, #endif를 넣어준다.#ifndef나 #define에 헤더 파일의 포함 여부를 알려주는 매크로 심볼을 지정한다.

12장. 고급 기능

헤더 파일의 중복 문제

분할 컴파일

62

Page 32: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

헤더 파일의 중복 피하기(2/2)보통 #ifndef와 #define 다음에 사용되는 매크로 심볼은 헤더 파일의 이름을 따서만든다.

이 매크로 심볼의 정의 여부로 헤더 파일이 포함되었는지를 확인한다.

가능한 모든 헤더 파일에 #ifndef, #define, #endif를 넣어주는 것이 안전하다.표준 C 라이브러리 헤더에도 이미 이 기능이 사용되고 있다.

12장. 고급 기능

헤더 파일의 중복 문제

분할 컴파일

63

헤더 파일의 중복 포함 막기(1/5)

12장. 고급 기능

헤더 파일의 중복 문제

분할 컴파일

64

01: /* Point.h */02: #ifndef POINT_H03: #define POINT_H04:05: struct point {06: int x;07: int y;08: };09: typedef struct point POINT;10:11: void PrintPoint(const POINT *p);12: void MovePoint(POINT *p, int dx, int dy);13: double GetDistance(const POINT *p1, const POINT *p2);14: void SetOrigin(int x, int y);15:16: extern POINT g_origin;17:18: #endif

Pont.h

헤더파일의중복포함막기

헤더파일의중복포함막기

Page 33: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

헤더 파일의 중복 포함 막기(2/5)

12장. 고급 기능

헤더 파일의 중복 문제

분할 컴파일

65

01: /* Point.c */02: #include <stdio.h>03: #include <math.h>04: #include "Point.h"05:06: POINT g_origin;07:08: void PrintPoint(const POINT *p)09: {10: printf("(%d, %d)\n", p->x, p->y);11: }12: void MovePoint(POINT *p, int dx, int dy)13: {14: p->x += dx;15: p->y += dy;16: }17:

Pont.c

헤더 파일의 중복 포함 막기(3/5)

12장. 고급 기능

헤더 파일의 중복 문제

분할 컴파일

66

18: double GetDistance(const POINT *p1, const POINT *p2)19: {20: int dx = p2->x - p1->x;21: int dy = p2->y - p1->y;22: return sqrt(dx*dx+dy*dy);23: }24:25: void SetOrigin(int x, int y)26: {27: g_origin.x = x;28: g_origin.y = y;29: }

Pont.c(continued)

Page 34: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

헤더 파일과 소스 파일의 구성

12장. 고급 기능

헤더 파일과 소스 파일의 구성

분할 컴파일

67

main 함수의 원형

명령행 인자(command-line parameter)main 함수로 전달되는 인자명령행 인자는 프로그램을 실행할 때 지정한다.

12장. 고급 기능

main 함수의 원형

main 함수의 매개변수

68

Page 35: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

명령행 인자를 처리하기 위한 main 함수의 원형

12장. 고급 기능

main 함수의 매개변수

main 함수의 매개변수

69

argc : 명령행 인자의 개수“myprog.exe test.dat”에서실행 파일명도 명령행 인자로 간주된다.

argv : 명령행 인자로 전달된문자열의 배열

명령행 인자의 사용 예

12장. 고급 기능

main 함수의 매개변수

main 함수의 매개변수

70

01: /* Ex12_08.c */02: #include <stdio.h>03:04: int main(int argc, char* argv[ ])05: {06: int i;07:08: for( i = 0 ; i < argc ; i++ )09: printf("argv[%d] = %s\n", i, argv[i]);10:11: return 0;12: }

명령행인자출력

매개변수를갖는main 함수

실행시 명령 프롬프트에서“Ex12_08.exe aaa bbb ccc”라고 지정한다.

Page 36: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

명령행 인자를 이용한 계산기 프로그램(1/2)

12장. 고급 기능

main 함수의 매개변수

main 함수의 매개변수

71

01: /* Ex12_09.c */02: #include <stdio.h>03: #include <stdlib.h>04:05: int main(int argc, char* argv[ ])06: {07: int lhs, rhs;08: char op;09:10: if( argc < 4 )11: {12: printf("Usage : Calc value1 op value2\n");13: return -1;14: }15:16: lhs = atoi(argv[1]);17: op = argv[2][0];18: rhs = atoi(argv[3]);19:

명령행인자의개수확인

매개변수를갖는main 함수

명령행인자사용

명령행 인자를 이용한 계산기 프로그램(2/2)

12장. 고급 기능

main 함수의 매개변수

main 함수의 매개변수

72

20: switch( op )21: {22: case '+':23: printf("%d + %d = %d\n", lhs, rhs, lhs+rhs);24: break;25: case '-':26: printf("%d - %d = %d\n", lhs, rhs, lhs-rhs);27: break;28: case '*':29: printf("%d * %d = %d\n", lhs, rhs, lhs*rhs);30: break;31: case '/':32: printf("%d / %d = %d\n", lhs, rhs, lhs/rhs);33: break;34: default :35: printf("잘못 입력하셨습니다.\n");36: break;37: }38:39: return 0;40: }

실행시 명령 프롬프트에서“Calc.exe 10 + 20”이라고 지정한다.

Page 37: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

헤더 파일의 중복 포함 막기(5/5)

12장. 고급 기능

헤더 파일과 소스 파일의 구성

분할 컴파일

73

17:18: printf("원점과 p2 사이의 거리 : %f\n",19: GetDistance(&g_origin, &p2));20:21: return 0;22: }

Main.c(continued)

헤더 파일의 중복 포함 막기(5/5)

12장. 고급 기능

헤더 파일과 소스 파일의 구성

분할 컴파일

74

17:18: printf("원점과 p2 사이의 거리 : %f\n",19: GetDistance(&g_origin, &p2));20:21: return 0;22: }

Main.c(continued)

Page 38: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

전처리기매크로 함수 : 함수처럼 인자를 갖는 매크로이다. 함수에 비해서 처리 속도는 빠르지만프로그램 크기가 커지는 단점이 있다.#define SQUARE(n) ((n) * (n))

전처리기 연산자 : 매크로 함수의 인자를 문자열로 만드는 # 연산자와 토큰을 결합하는 ## 연산자가 있다.#define PRINT(x) printf(#x" = %d\n", x);#define MAKE_FUNC(name) void fn##name(void) { printf("fn"#name" 호출\n"); }

조건부 컴파일 : 조건이 만족할 때 특정 문장을 컴파일한다. #if, #ifdef, #ifndef 등이 있고, 각각은 #endif가 필요하다.#ifdef DEBUG

printf("GetFactorial 호출\n");#endif

12장. 고급 기능

학습정리

75

분할 컴파일#include : 다른 파일의 내용을 소스 파일에 복사해서 넣어준다.#include <라이브러리 헤더>#include "사용자 정의 헤더"

헤더 파일과 소스 파일

main 함수의 매개변수main 함수의 원형int main(int argc, char *argv[]);

main 함수의 매개변수 : argc는 명령행 인자의 개수이고, argv는 명령행 인자 문자열의 배열이다.

12장. 고급 기능

학습정리

76

Page 39: 12장 고급기능 - mm.sookmyung.ac.krmm.sookmyung.ac.kr/~bigrain/class/2012/c/chap12.pdf · 조건이참이면문장1을컴파일하고, 조건1이거짓이면문장2를컴파일한다

12장. 고급기능

77

NEXT Chapter

13장. 입출력 라이브러리

수고하셨습니다.질문 있습니까?