IT공부/윤성우 열혈 C프로그래밍
C언어의 깊은 이해_4
doublehyun
2022. 3. 6. 21:40
Chapter.6 매크로와 선행처리기
- 선행처리기와 매크로
- 선행처리기 : 컴파일 이전의 처리
- 선행처리 명령대로 소스코드의 일부를 단순 치환한다 이때 #을 붙이고, 세미콜론은 붙이지 않는다
- 대표적인 선행처리 명령문
- #define PI 3.141592
- #define(지시자), PI(매크로), 3.141592(매크로 몸체) 라 표현한다
- 뜻은 매크로PI를 매크로몸체 3.14~로 치환해라 라는 뜻
- #define SQUARE(X) X*X
- 함수와 유사한 메크로(functuon-like macro) 즉 매크로 함수 이다
- SQUARE(X) 등장시 X*X로 치환하라는 뜻이다 ex) SQUARE(123) -> 123*123
- 잘못된 매크로 정의
- ex) SQUARE(3+2) 의 경우 3+2*3+2 = 11이 출력된다(25가 아니라)
- 이때 3+2에 괄호를 쳐주면 (3+2)*(3+2) = 25로 정상적인 값이 나오게 된다
- 따라서 매크로 몸체에 괄호를 쳐준다 SQUARE(X) ( (X)*(X) ) // 매개변수에 괄호, 전체 함수에 괄호
- 두줄에 걸쳐 매크로 정의하기
- define SQUARE(X) \
- ((X)*(X))
- 매크로 정의 시, 먼저 정의된 매크로도 사용 가능!
- 매크로 함수의 장점
- 일반 함수에 비해 실행속도가 빠르다
- 자료형에 따라 별도로 함수를 정의하지 않아도 된다
- 매크로 함수의 단점
- 정의하기가 정말로 까다롭다
- 디버깅 하기가 쉽지 않다
- 따라서 매크로 할 함수의 특징
- 작은 크기의 함수
- 호출의 빈도수가 높은 함수
- #define PI 3.141592
- 조건부 컴파일을 위한 매크로
- #if... ~ #endif = 참이라면
- #if 뒤에 오는 인자가 참이면 #endif 전까지 있는 코드 컴파일, 참이 아니면 #endif 전까지 있는 코드 생략!
- #ifdef... ~ #endif = 정의 되었다면
- #ifdef 뒤에 오는 매크로가 정의되어 있으면 #endif 전까지 있는 코드 컴파일, 정의되지 않으면 #endif 전까지 있는 코드 생략!
- #ifndef... ~ #endif = 정의 되었다면
- #ifndef 뒤에 오는 매크로가 정의되지 않으면 #endif 전까지 있는 코드 컴파일, 정의되어 있으면 #endif 전까지 있는 코드 생략!
- #else의 삽입
- #if, #ifdef, #ifndef 에 사용 가능하다
- if문과 동일하게 사용된다
- #elif의 삽입
- #if 문에만 사용 가능하고 여러번 사용 가능하다
- if문의 elseif와 동일하게 사용된다
- #if... ~ #endif = 참이라면
- 매개변수의 결합과 문자열화
- 문자열 내에서는 매크로의 매개변수 치환이 발생하지 않는다
- ex) define ST_job(A, B) "A의 직업은 B입니다" 선언후 ST_job(이중현, 학생) 실행시 A의 직업은 B입니다 가 치환된다
- 따라서 문자열 내에서 매크로를 치환하려면 # 연산자를 사용면 된다
- ex) define ST_job(A, B) #A "의 직업은" #B "입니다" 는 이중현의 직업은 학생입니다 로 치환된다
- 필요한 형태대로 단순하게 결합하기 : 매크로 ##연산자
- ex) define STNUM(Y, S, P) Y ## S ## P 선언후 STNUM(18, 11, 21) 은 181121 로 치환된다
- 문자열 내에서는 매크로의 매개변수 치환이 발생하지 않는다
Chapter.7 파일의 분할과 헤더파일의 디자인
- 파일의 분할
- 컴파일러는 파일 단위로 컴파일을 진행한다, 따라서 다른 파일의 정보를 참조하여 컴파일을 진행하지 않는다
- 외부에 선언 및 정의되어 있다면 컴파일러에게 미리 알려줘야 한다!!
- extern int num; -> 외부에 int num 이라는 변수가 선언되어 있다 라고 알려준다
- 다른 파일에서 접근을 못하게 막고 싶다면 static을 선언하면 된다 (static int num;) -> 접근 범위를 파일 내부로 제한한다
- 헤더파일의 디자인과 활용
- #include 지시자의 의미 = 이 문장의 위치에 해당 파일에 저장된 내용을 가져다 놓으세요
- 헤더파일을 include 하는 두가지 방법
- #include <헤더파일 이름> = C의 표준에서 정의하는, 기본적으로 제공되는 헤더파일을 포함시킬때 사용
- #include "헤더파일 이름" = 프로그래머가 정의한 헤더파일을 포함시킬때 사용
- 헤더파일에 담겨야 하는 내용
- extern 이 선언되어야 하는 함수, 변수를 미리 선언해 놓는다
- 구조체를 저장해 사용할 경우 헤더파일에 저장해서 모두 사용할 수 있게 한다
- 헤더파일의 중복 삽입 문제
- 다음과 같은 경우 구조체 div가 두번 삽입된 형태가 되어 컴파일 에러가 발생한다
- 헤더파일의 중복 삽입이 문제가 아니라 구조체의 중복 선언이 문제
- 이때 #ifndef __STDIV_H__ 를 사용해 조건부 컴파일을 사용하면 된다 (크게 의미없는 매크로를 사용한다)
- ex) stdiv2.h 헤더파일 구현시
- #ifndef __STDIV2_H__
- #define__ STDIV2_H__
- ~~ ~~ ~~
- #endif
- 를 사용해서 중복 삽입이 됬을 경우 컴파일이 되지 않게 선언해주면 된다(중복 선언은 되지만, 안에 내용이 없는 상태로 치환되기 때문에 문제가 발생하지 않음)