제13장 전처리 및 기타기능
이번 장에서 학습할 내용 전처리와 기타 중요한 테마에 대하여 학습한다. 전처리 지시어 분할 컴파일 명령어 라인의 매개변수 디버깅 방법
전처리기란? 전처리기 (preprocessor)는 컴파일하기에 앞서서 소스 파일을 처리하는 컴파일러의 한 부분
전처리기의 요약 지시어 의미 #define 매크로 정의 #include 파일 포함 #undef 매크로 정의 해제 #if 조건이 참일 경우 #else 조건이 거짓일 경우 #endif 조건 처리 문장 종료 #ifdef 매크로가 정의되어 있는 경우 #ifndef 매크로가 정의되어 있지 않은 경우 #line 행번호 출력 #pragma 시스템에 따라 의미가 다름
단순 매크로 단순 매크로(macro): 숫자 상수를 기호 상수로 만든 것 (예) #define MAX_SIZE 100 #define PI 3.141592 #define EPS 1.0e-9
단순 매크로
단순 매크로의 장점 프로그램의 가독성을 높인다. 상수의 변경이 용이하다. 기호 상수를 사용하는 경우 숫자를 사용하는 경우
단순 매크로의 예 2147483647보다는 MAX_INT가 낫죠 사람은 숫자보다 기호를 잘 기억합니다.
중간 점검 숫자 상수를 기호 상수로 정의하는 데 사용되는 전처리 지시자는 #_________이다. #define을 이용하여서 하나의 텍스트를 다른 텍스트로 정의할 수 있는가? define #define SCAN scanf
함수 매크로 함수 매크로(function-like macro)란 매크로가 함수처럼 매개 변수를 가지는 것 (예) #define SQUARE(x) ((x) * (x))
함수 매크로의 예 #define SUM(x, y) ((x) + (y)) #define AVERAGE(x, y, z) (( (x) + (y) + (z) ) / 3 ) #define MAX(x,y) ( (x) > (y) ) ? (x) : (y) #define MIN(x,y) ( (x) < (y) ) ? (x) : (y)
주의할 점 #define SQUARE(x) x*x // 위험 !! v = SQUARE(a+b); v = a + b*a + b; 함수 매크로에서는 매개 변수를 괄호로 둘러싸는 것이 좋습니다. #define SQUARE(x) (x)*(x) // 올바른 형태
예제 ((++x) * (++x)) 4 9 1.440000 25 16
함수 매크로의 장단점 함수 매크로의 장단점 간단한 기능은 매크로를 사용 함수 호출 단계가 필요없어 실행 속도가 빠르다. 소스 코드의 길이가 길어진다. 간단한 기능은 매크로를 사용 #define MIN(x, y) ((x) < (y) ? (x) : (y)) #define ABS(x) ((x) > 0 ? (x) : -(x))
중간 점검 함수 매크로는 함수보다 속도가 느린가? 3제곱을 수행하는 함수 매크로를 정의하여 보자. 함수 매크로를 사용하는 것이 함수를 사용하는 것보다 실행 속도가 빠르다. #define ABS(x) ((x)>0?(x):-(x))
#ifdef 어떤 조건이 만족되었을 경우에만 컴파일하는 조건부 컴파일 지시 #ifdef 매크로 문장1 // 매크로가 정의되었을 경우 … #else 문장2 // 매크로가 정의되지 않았을 경우 #endif
#ifdef의 예
예제
예제
비주얼 C++에서 설정하는 방법
중간 점검 전처리기 지시자 #ifdef을 사용하여 TEST가 정의되어 있는 경우에만 화면에 “TEST"라고 출력하는 문장을 작성하여 보자. #ifdef TEST printf("TEST\n"); #endif
#if 기호가 참으로 계산되면 컴파일 조건은 상수이어야 하고 논리, 관계 연산자 사용 가능
#if-#else-#endif (예)
다양한 예
다양한 예
조건부 컴파일을 이용하는 디버깅
조건부 컴파일을 이용하는 디버깅
다수의 라인을 주석처리
예제 정렬 알고리즘을 선택
중간 점검 #if를 사용하여 DEBUG가 2일 경우에만 “DEBUG"가 나오도록 문장을 작성하라. #if를 사용하여 DEBUG가 2이고 LEVEL이 3인 경우에만 “DEBUG"가 나오도록 문장을 작성하라.
다중 소스 파일 단일 소스 파일 다중 소스 파일 파일의 크기가 너무 커진다. 소스 파일을 다시 사용하기가 어려움 서로 관련된 코드만을 모아서 하나의 소스 파일로 할 수 있음 소스 파일을 재사용하기가 간편함
헤더 파일 이중 포함 방지 /*** *stdio.h - definitions/declarations for standard I/O routines ****/ #ifndef _INC_STDIO #define _INC_STDIO .... #endif 헤더 파일이 포함되면 매크로가 정의되어서 이중 포함을 방지합니다.
다중 소스 파일
예제 power.h multiple_source.c power.c
헤더 파일을 사용하지 않으면
헤더 파일을 사용하면
다중 소스 파일에서 외부 변수
비주얼 C++에서 다중 소스 파일
중간 점검 다음 문장의 참 거짓을 말하라. “여러 소스 파일을 이용하는 것보다 하나의 소스 파일로 만드는 편이 여러모로 유리하다.” 팩토리얼을 구하는 함수가 포함된 소스 파일과 관련 헤더 파일을 제작하여 보자. 여러 소스 파일로 만드는 편이 소스를 유지, 보수, 관리하기가 편리하다.
main() 함수의 인수 지금까지의 main() 함수 형태 외부로부터 입력을 받는 main() 함수 형태
인수 전달 방법 C: \cprogram> mycopy src dst
main_arg.c Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. c:\cprogram\mainarg\Debug>mainarg src dst 명령어 라인에서 0번째 문자열 = mainarg 명령어 라인에서 1번째 문자열 = src 명령어 라인에서 2번째 문자열 = dst c:\cprogram\mainarg\Debug>
비주얼 C++ 프로그램 인수 입력 방법
mile2km.c Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. c:\cprogram\mainarg\Debug>mainarg 10 입력된 거리는 16.090000 km입니다. c:\cprogram\mainarg\Debug>
중간 점검 main()의 argv[0]에는 무엇이 들어 있는가? “C>test a b c” 라고 도스 창에서 입력하였다면 argc, arv[]에는 어떤 값들이 들어 가는가? 실행파일의 이름이 저장되어 있다. argc=4 argv[0]="test" argv[1]="a" argv[2]="b" argv[3]="c"
디버깅 소스에 존재하는 오류를 잡는 것
디버깅 디버깅: 논리 오류를 찾는 과정
디버거의 실행 과정
디버거의 실행 과정
디버거의 실행 과정
디버거의 명령어 정의 디버그 시작 다시 시작 디버깅 중지 한 단계씩 코드 실행 프로시저 단위 실행 프로시저 나가기 간단한 조사식 조사식 레지스터 메모리 호출스택 디어셈블리 중단점 설정/해제 디버그 시작
중간 점검 디버깅시에 단축기 F10과 F11의 차이점은 무엇인가? 중단점(breakpoint)이란 무엇인지 인터넷에서 조사하여 보자. F10: 함수 호출을 만나면 함수 호출을 하나의 문장으로 간주하고 실행한다. F11: 함수 호출을 만나면 그 함수 안으로 진입한다. 중단점(breakpoint)란 디버깅의 목적으로 사용자가 실행을 중단하고 싶은 문장에 표시를 하는 것
비트 단위 연산자 C에서는 비트 단위의 연산도 가능하다. 비트 단위 연산자는 정수에만 적용이 가능하다. 연산자 연산자의 의미 설명 & 비트 AND 두개의 피연산자의 해당 비트가 모두 1이면 1, 아니면 0 | 비트 OR 두개의 피연산자의 해당 비트중 하나만 1이면 1, 아니면 0 ^ 비트 XOR 두개의 피연산자의 해당 비트의 값이 같으면 0, 아니면 1 << 왼쪽으로 이동 지정된 개수만큼 모든 비트를 왼쪽으로 이동한다. >> 오른쪽으로 이동 지정된 개수만큼 모든 비트를 오른쪽으로 이동한다. ~ 비트 NOT 0은 1로 만들고 1은 0로 만든다.
비트 단위 연산자 비트 연산 표 X Y AND OR XOR 1 X NOT 1
비트 논리곱 연산자 비트1 비트2 비트1 & 비트2 1 마스크 연산으로 많이 사용
비트 논리합 연산자 비트1 비트2 비트1 | 비트2 1 비트설정연산으로 많이 사용
비트 배타 논리합 연산자 비트1 비트2 비트1 ^ 비트2 1
비트 부정 연산자 비트1 ~비트1 1
예제 비트 AND = 00000008 비트 OR = 0000000B 비트 XOR = 00000003 비트 NOT = FFFFFFF6
비트 이동 연산자 왼쪽 비트 이동 연산 연산자 기호 설명 왼쪽 비트 이동 << x << y x의 비트들을 y 칸만큼 왼쪽으로 이동 오른쪽 비트 이동 >> x >> y x의 비트들을 y 칸만큼 오른쪽으로 이동 왼쪽 비트 이동 연산
오른쪽 비트 이동 연산(양수) 오른쪽 비트 이동 연산(양수)
오른쪽 비트 이동 연산(음수) 오른쪽 비트 이동 연산(음수)
예제 비트 << = 00000024 비트 >> = 00000002
중간 점검 비트를 지정된 숫자만큼 왼쪽으로 이동시키는 연산자는 ________이다. 비트의 값을 0에서 1로, 1에서 0으로 바꾸는데 사용하는 연산자는 ________이다. 변수 x의 값을 2배로 하려면 ________쪽으로 비트를 이동시키면 된다. 변수 x의 값을 1/2배로 하려면 _________쪽으로 비트를 이동시키면 된다. << ~ 왼쪽 오른쪽
비트 필드 구조체 멤버가 비트 단위로 나누어져 있는 구조체 struct 태그이름 { 자료형 멤버이름1: 비트수; 자료형 멤버이름2: 비트수; ... }; struct product { unsigned style : 3; unsigned size : 2; unsigned color : 1; };
bit_field.c style=5 size=3 color=1 sizeof(p1)=4 p1=ccccccfd
비트 필드 사용시에 주의점 비트 필드의 응용 분야: 하드웨어 포트 제어
중간 점검 구조체의 일종으로 멤버들의 크기가 비트 단위로 나누어져 있는 구조체는 _________________이다. 비트 필드 구조체를 정의하는 경우, 자료형은 __________이나 _____________을 사용하여야 한다. 비트 필드 구조체 unsigned unsigned int
Q & A