Presentation is loading. Please wait.

Presentation is loading. Please wait.

쉽게 풀어쓴 C언어 Express 제15장 전처리 및 비트 필드 C Express.

Similar presentations


Presentation on theme: "쉽게 풀어쓴 C언어 Express 제15장 전처리 및 비트 필드 C Express."— Presentation transcript:

1 쉽게 풀어쓴 C언어 Express 제15장 전처리 및 비트 필드 C Express

2 이번 장에서 학습할 내용 전처리와 기타 중요한 테마에 대하여 학습한다. 전처리 지시자 다중 소스 프로그램 비트 필드

3 전처리기란? 전처리기(preprocessor): 컴파일에 앞서 소스 파일을 처리 수고했어, 나머지는 나한테 맡겨!
#include, #define 등을 처리 합니다. 소스 파일 임시 파일 오브젝트 파일 전처리기 컴파일러

4 단순 매크로 단순 매크로(macro): 기호 상수 정의 전처리기 #define SIZE 100
사람은 숫자보다 기호를 잘 기억 하므로 보다는 PI가 낫죠! #define SIZE 100 #define PI #define SIZE 100 while (i < SIZE) { sum += i; i++; } while (i < 100) { sum += i; i++; } 전처리기

5 단순 매크로의 장점 프로그램의 가독성 향상 상수 변경이 용이 리터럴을 사용하는 경우: 모든 곳을 수정해야 함
기호 상수를 사용하는 경우: 정의된 부분만 수정하면 됨

6 단순 매크로의 예 #define SIZE 100 // 배열 크기 #define MAX_INT 2147483647 // 최대정수
#define PI // 원주율 #define TWOPI ( * 2.0) // 원주율의 2배 #define EOF (-1) // 파일의 끝 표시 #define DIGITS " " // 문자열 상수 정의 #define BRACKET "(){}[]" // 문자열 상수 정의 #define MAX_LEN // 문자열 최대 길이 #define MAX_SIZE (MAX_LEN + 1) // 문자 배열 최대 크기 #define EXPR x = y + 1; p = "abc" // 어떤 형태라도 정의 가능

7 함수형 매크로 함수형 매크로: 함수처럼 인자를 가질 수 있는 매크로 #define SQUARE(x) ((x) * (x))
v = SQUARE(3); v = ((3) * (3)); #define SUM(x, y) ( (x) + (y) ) #define AVERAGE(x, y, z) ( ( (x) + (y) + (z) ) / 3 ) #define MAX(x, y) ( (x) > (y) ) ? (x) : (y) ) #define ABS(x) ( (x) < 0 ) ? -(x) : (x) ) #define getchar() getc(stdin) #define putchar(c) putc((c), stdout)

8 주의할 점 #define SQUARE(x) x * x // 위험 !! v = SQUARE(1 + 2);
함수형 매크로에서는 인자와 전체를 괄호로 둘러싸는 것이 안전합니다.

9 함수형 매크로의 장단점 함수 호출보다 실행 속도가 빠름 큰 매크로를 많이 사용하면 실행 프로그램 크기 증가 디버깅이 어려움
함수에 비해 위험 #define SQUARE(x) ((x) * (x)) n = 1; v = SQUARE(++n); //  v = ((++n) * (++n)); // n = 3, v = 9 or 6 int square(int x) { return x * x; } n = 1; v = square(++n); // n = 2, v = 4

10 예제 #include <stdio.h> #define SQUARE(x) ((x) * (x))
int main(void) { int x = 2; printf("%d\n", SQUARE(x)); printf("%d\n", SQUARE(3)); printf("%f\n", SQUARE(1.2)); printf("%d\n", SQUARE(x+3)); printf("%d\n", 100/SQUARE(x)); printf("%d\n", SQUARE(++x)); // 논리 오류 return 0; } 4 9 25 16

11 매크로 정의 해제 #undef 매크로: 매크로에 대한 정의 취소(undefine)
#define SIZE 10 #undef SIZE int SIZE; 긴 매크로 처리 방법: 한 줄 이상이면 반드시 끝에 연속 마크(\) 사용 #define OUT_ERROR(code, message) \ printf("[%d] %s\n", \ (code), (message))

12 매크로 연산자 # 연산자: 매크로 인자를 문자열로 변환 (전위 단항 연산자)
#define PRINT(exp) printf(#exp " = %d\n", (exp)) x = 1; PRINT(x + 2); // printf("x + 2" " = %d\n", (x + 2)); //  printf("x + 2 = %d\n", (x + 2)); //  x + 2 = 3 ## 연산자: 하나의 토큰으로 병합 (이항 연산자) #define VAR(n) v##n #define TOKEN(name, n) name ## n VAR(1) = 2; // v1 = 2; s = TOKEN(sum, 2); // s = sum2;

13 예제 #include <stdio.h> #define MAKE_NAME(n) v ## n
#define PRINT(n) printf("v" #n " = %d\n", MAKE_NAME(n)); int main(void) { int MAKE_NAME(1) = 10; // int v1 = 10; int MAKE_NAME(2) = 20; // int v2 = 20; PRINT(1); // printf("v1 = %d\n", v1); PRINT(2); // printf("v2 = %d\n", v2); return 0; } v1 = 10 v2 = 20

14 내장 매크로 내장 매크로: 미리 정의된 매크로 매크로 값 __DATE__ 컴파일 날짜(문자열) __TIME__
컴파일 시간(문자열) __FILE__ 소스 파일 이름(문자열) __LINE__ 현재 라인 번호(정수) printf("컴파일 시간 = %s %s\n", __DATE__, __TIME__); // 컴파일 시간 = Oct :03:04 printf("에러 발생: 파일 이름 = %s, 라인 번호 = %d\n", __FILE__, __LINE__);

15 예제: ASSERT 매크로 #include <stdio.h> #include <stdlib.h>
#define ASSERT(exp) \ if (!(exp)) \ printf("[%s %d] 조건 실패: " #exp "\n", __FILE__, __LINE__), exit(1) int main(void) { int sum; ASSERT(sum == 0); return 0; } [assert.c 10] 조건 실패: sum == 0

16 비트 조작 매크로 #define BIT_GET(w, k) (((w) >> (k)) & 0x01)
결과: 0 / 1 #define BIT_SET (w, k) ((w) | 0x01 << (k)) w의 k번째 비트를 1로 설정 #define BIT_RESET(w, k) ((w) & ~(0x01 << (k))) w의 k번째 비트를 0로 설정

17 예제: 비트 조작 매크로 #include <stdio.h>
#define BIT_GET(w, k) (((w) >> (k)) & 0x01) #define BIT_SET(w, k) ((w) | 0x01 << (k)) #define BIT_RESET(w, k) ((w) & ~(0x01 << (k))) int main(void) { int data = 0; data = BIT_SET(data, 2); printf("%08X %d\n", data, BIT_GET(data, 2)); data = BIT_RESET(data, 2); return 0; }

18 조건부 컴파일 지시자 #if 조건: 조건이 참이면 조건: 정수 상수 조건이어야 하고 논리, 관계 연산자 등 허용
#ifdef 매크로: 매크로가 정의되어 있으면 #ifdef M  #if defined(M) defined(M): 전처리 연산자, 매크로 M이 정의되어 있으면 참 #ifndef 매크로: 매크로가 정의되어 있지 않으면 #ifndef M  #if !defined(M) #else: 그렇지 않으면 #elif 조건: 그렇지 않고 조건이 참이면 (else if) #endif: 조건부 컴파일 지시자 끝 #if / #ifdef / #ifndef … #endif

19 조건부 컴파일 지시자 예 #if DEBUG_LEVEL >= 1 printf("result = %d\n", result);
#endif #ifdef LINUX ... // LINUX 버전인 경우 #else ... // LINUX 버전이 아닌 경우 #endif #if NATION == 1 #include "korea.h" #elif NATION == 2 #include "china.h" #else #include "usa.h" #endif #ifndef LIMIT // LIMIT이 정의되어 있지 않으면 # define LIMIT 1000 #endif #if 0 // 전처리 기능을 이용한 주석 처리 #endif

20 예제 #include <stdio.h> #define DELUXE int main(void) {
#ifdef DELUXE printf("딜럭스 버전입니다.\n"); #endif return 0; } 딜럭스 버전입니다.

21 조건부 컴파일 지시자 #if VERSION > 3 // 가능! 버전이 3보다 크면
#if (AUTHOR == KIM) // 가능! KIM은 매크로 #if (VERSION * 10 > 500 && LEVEL == BASIC) // 가능! #if (VERSION > 3.0) // 오류! 실수는 허용되지 않음 #if (AUTHOR == "CHULSOO") // 오류! 문자열은 허용되지 않음 #if (VERSION > 300 || defined(DELUXE)) // 가능!

22 #include #include <…> 표준 디렉토리(폴더)에서 파일 탐색 #include "…"
현재 디렉토리에서 파일 탐색  표준 디렉토리에서 파일 탐색 (현재 디렉토리에 없는 경우) 경로 지정 가능 #include "graphic/point.h" #include "D:\Project\source\point.h" #include "/home/user1/source/point.h"

23 헤더 파일 중복 포함 방지 // rect.h #ifndef RECT_H #define RECT_H // rect.h
struct rect { int x, y, w, h; }; #endif // rect.h struct rect { int x, y, w, h; }; // shape.h #include "rect.h" // shape.h #ifndef SHAPE_H #define SHAPE_H #include "rect.h" #endif // main.c #include <stdio.h> #include "rect.h" #include "shape.h"

24 다중 소스 파일 단일 소스 파일 다중 소스 파일 소스의 재사용과 관리가 어려움
일부만 수정한 경우에도 전체를 다시 컴파일해야 함 다중 소스 파일 모듈별로 별도의 소스 파일 유지  소스의 재사용과 관리가 용이함 변경된 소스 파일만 다시 컴파일  컴파일 시간 단축

25 다중 소스 파일 라이브러리

26 예제 power.h main.c #ifndef POWER_H #define POWER_H
double power(int x, int y); #endif #include <stdio.h> #include "power.h" int main(void) { int x,y; printf("x의 값을 입력하시오: "); scanf("%d", &x); printf("y의 값을 입력하시오: "); scanf("%d", &y); printf("%d의 %d 제곱값은 %f\n", x, y, power(x, y)); return 0; } power.c #include "power.h" double power(int x, int y) { double result = 1.0; int i; for (i = 0;i < y; i++) result *= x; return result; } x의 값을 입력하시오: 2 y의 값을 입력하시오: 3 2의 3 제곱값은

27 헤더 파일을 사용하지 않으면 함수 원형 선언 반복

28 헤더 파일을 사용하면 헤더 파일 포함

29 다중 소스 파일에서 외부 변수

30 비트 필드 int/unsigned 타입의 구조체 필드는 비트 단위로 크기 지정 가능  비트 필드
메모리 절약 struct product { unsigned style : 1; // [0, 1] unsigned size : 2; // [0, 3] int value : 5; // [-16, +15] }; int/unsigned (word) value size style

31 예제 ? … 1 #include <stdio.h> struct product { unsigned style : 1;
unsigned size : 2; int value : 5; }; int main(void) { struct product p; p.style = 1; p.size = 2; p.value = -10; printf("style = %u, size = %u, value = %d\n", p.style, p.size, p.value); printf("sizeof p = %d\n", sizeof p); printf("p = %08X\n", p); return 0; } style = 1, size = 2, value = -10 sizeof p = 4 p = B5 ? 1 value size style

32 비트 필드 code struct product { int code; // 일반 멤버 unsigned style : 1;
unsigned size : 2; int value : 5; unsigned : 0; // 현재 워드의 나머지 비트는 사용하지 않음 unsigned state : 4; // 다음 워드에 할당 }; code value size style state


Download ppt "쉽게 풀어쓴 C언어 Express 제15장 전처리 및 비트 필드 C Express."

Similar presentations


Ads by Google