전처리 지시자는 왜 사용해야 하는가?
프로그램은 컴파일 환경을 바꾸거나
여러 개의 모듈로 나누어 작성할 때
이식성과 호환성을 고려해야 한다.
때문에 컴파일하기 전에 컴파일 환경에 맞게
소스 코드를 편집할 수 있는 기능이 필요한데,
그 기능을 담당하는 것이 전처리 지시자이다.
전처리 지시자의 종류
- 파일을 포함하는 #include
- 매크로명을 만드는 #define
- #define을 사용한 매크로 함수
- 매크로 연산자 #과 ##
- 조건부 컴파일 지시자
- #pragma 지시자
+PUSE
분할 컴파일
1. 파일을 포함하는 #include
#include 는 지정한 파일의 내요을 읽어와 지시자가 있는 위치에 붙여놓는다.[솔루션 탐색기] - [해더 파일]에서 마우스를 우클릭 한 다음 [추가] - [새 항목] 을 선택하여, [이름]에 해더 파일의 명.h를 입력하면#include 할 수 있다.
꺽쇠괄호 참조와 ( < > ) 큰 따옴표 ( " " ) 의 차이는 무엇일까?
꺽쇠괄호 참조를 하면,복사할 파일을 컴파일러가 설정한 include 디렉터리에서 찾고,
큰따옴표를 사용하면,
소스 파일이 저장된 디렉터리에서 먼저 찾는다.
(= 큰 따옴표는 사용자가 만든 헤더 파일을 의미)
다른 디렉터리에 있는 파일을 포함할 수 있는데
이때는 경로를 포함한 파일명을 사용한다.
아래 예제를 참고하면 이해가 편하다.
< 예 제 1 >
#include "c:\user\myhdr.h" |
#include 는 사실 파일의 내용을 단순히 복사하여 붙여넣는 기능을 한다.
따라서 텍스트 형태의 파일이라면 모두 사용 가능하며,
심지어 실제로 소스 파일을 포함하는 것도 가능하다.
예를 들어 main 함수 중간에 들어가는 코드를 따로 떼어
헤더 파일로 만든 후 인클루드 하는 것도 가능하다.
마지막으로 전처리 과정이 끝난 후의 파일 형태를 생각해보면,
전처리 과정은 소스 파일에 다른 파일의 내용을 포함시키거나 일부 문장을
다른 문장으로 바꾸는 등 소스 파일을 편집하는 일을
주로 수행하므로 전처리된 후의 파일도
소스 파일과 형태가 같은 텍스트 파일임을 기억해두자.
2. 매크로명을 만드는 #define
#define은 매크로명을 정의하는 전처리 지시자로 사용법은 다음과 같다.
매크로명은 다른 변수명과 쉽게 구분 가능하도록 관례상 대문자를 사용하고,
치환될 부분은 매크로명과 하나 이상의 빈칸을 둔다.
< 예 시 1 >
#define 매크로명 치환될_부분 |
3. #define을 사용한 매크로 함수
매크로 함수는 인수에 따라 서로 다른 결괏값을 갖도록 치환된다.
따라서 비록 함수는 아니지만 인수를 주고 함수처럼 쓸 수 있다.
매크로 함수를 만들 때는 매크로명에 괄호를 열고 인수를 나열한다.
< 예 시 1 >
#define 매크로_함수명(인수) 치환될_부분 |
매크로 함수는 함수처럼 쓰이지만 치환된 후 발생할 문제를 예측하기는 어렵다.
또한 많은 기능을 매크로 함수로 구현하기는 수정하기 쉽지 않다.
그러나 매크로 함수는 호출한 함수로 이동할 때 필요한 준비작업이 없으므로
함수 호출보다 상대적으로 실행 속도가 빠르다.따라서 크기가 작은 함수를 자주 호출한다면 매크로 함수가 도움이 될 수 있다.
+plus
이미 정의된 매크로
매크로에는 이미 그 정의가 약속되어 있어 사용자가 취소하거나바꿀 수 없는 매크로명이 있다.그 종류는 다양하고 컴파일러나 버전에 따라 다를 수 있으므로디버깅에 유용한 다음 몇가지만 소개하겠다.
4. 매크로 연산자 #과 ##
매크로 함수를 만들 때 매크로 연산자를 사용하면
인수를 특별한 방법으로 치환할 수 있다.
#은 매크로 함수의 인수를 문자열로 치환하고
##은 두 인수를 붙여 치환한다.
## 연산자는 2개의 토큰을 붙여서 하나로 만드는 연산자이다.
토큰은 프로그램에서 독립된 의미를 갖는 하나의 단위로
9행은 각각 다른 2개의 토큰 a와 1을 하나로 붙여서
변수명 a1으로 사용하도록 치환한다.
5. 조건부 컴파일 지시자
조건부 컴파일은 소스 코드를 조건에 따라 선택적으로 컴파일한다.
이떄 #if, #else, #elif, #ifdef, #ifndef, #endif 등의 전처리 지시자를
다양한 방법으로 조합하여 사용한다.
6. #pragma 지시자
#pragma 지시자는 컴파일러의 컴파일 방법을 세부적으로 제어할 때 사용한다.
사용법은 지시명 directive - name을 통해
컴파일러의 어떤 기능을 제어할 것인지 알려준다.
pack은 구조체의 패딩 바이트 크기를 결정하며,
warning 은 경고 메시지를 관리한다.
+ 바이트 얼라이먼트(Byte alignment)
하드웨어의 제약이나 성능상의 이유로 데이터들을
특정 바이트 경계에 맞게 배치하는 것으로
이를 바이트 정렬이라고 부른다.
ex)
32bit )
4 bytes -> 2 bytes -> 1 byte
62bit )
8 bytes -> 4 bytes -> 2 bytes -> 1 byte
분할 컴파일
분할 컴파일이란?
하나의 프로그램을 여러 사람이 나누어 개발할 수 있다면
프로그램의 크기가 커도 충분히 개발 기간을 줄일 수 있다.
단 2가지 문제를 해결해야 하는데,
하나는 개별적으로 코드를 작성하고 컴파일 및 에러 수정이 가능해야 하고,
두 번째는 각 개발자들 간의 데이터 공유와 코드 재활용이 가능해야 한다.
C언어는 분할 컴파일을 통해 여러 개의 소스 코드를 각각 독립적으로 작성하고
컴파일 하는 것이 가능하며,
컴파일된 개체 파일을 링크하여 하나의 큰 프로그램으로 만들 수 있다.
또한 exturn 선언을 통해 파일들 간에 데이터를 공유하고
전처리 지시자로 코드를 쉽게 재활용할 수 있다.
분할 컴파일의 방법
분할 컴파일은 하나의 프로그램을 여러 개의 파일로 나누어 작성하면 된다.
비주얼 스튜디오와 같은 통합 개발환경에서 분할 컴파일하는 것은 어렵지 않다.
각 파일을 독립적으로 컴파일할 수 있도록 필요한 선언을 포함하면 된다.
한번 기능이 검증된 소스 파일은 다른 프고르램에서도 사용할 수 있으니,
코드의 재활용에 도움이 된다.
분할 컴파일에서 extern과 static의 용도
다른 파일에서 선언된 전역 변수를 사용할 때는 extern 선언을 한다.
다른 파일에서 전역 변수를 공유하지 못하게 할 땐 static을 쓴다.
'프로그래밍 언어 > C & C++ 정리' 카테고리의 다른 글
인라인 함수 (0) | 2023.01.09 |
---|---|
C++ 기초 플러스 단원 정리 (0) | 2023.01.08 |
동적 할당 함수 (0) | 2023.01.07 |
c++ 함수의 특질 (0) | 2023.01.07 |
함수 (0) | 2023.01.06 |