일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 프로그래밍
- 문법
- 연산자
- Javascript
- Tips프로그래밍강좌
- Desktop
- c#
- Direct2D
- 함수
- Windows
- VS ERROR
- Tips강좌
- tipssoft
- 이지스퍼블리싱
- 백준
- Visual Studio
- Kotlin
- doit코틀린프로그래밍
- Programming
- 김성엽
- 티스토리
- 지식나눔강좌
- 리뷰
- 포인터
- Win32
- 배열
- 알고리즘
- c
- c++
- CS
- Yesterday
- Today
- Total
F.R.I.D.A.Y.
define VS typedef 본문
오랜만에 찾아왔습니다. 이번 시간에는 비슷해 보이면서도 다른, define과 typedef에 대해 알아봅니다. 사실 define과 typedef는 엄연히 다르지만, 주변을 보면 혼용해서 사용하는 것을 보고 작성하는 겁니다. 제대로 된 차이를 알리기 위해 글의 시작은 define과 typedef의 설명으로 시작합니다.
define
define은 전처리 지시자입니다. 전처리 지시자에 대한 내용은 다음 문서(MS DOCS, ENG)를 참고하세요. 이 전처리기는 컴파일 전에 시행되어 전처리 지시자로 선언된 항목을 일괄적으로 고친 후, 이렇게 고친 코드를 컴파일하게 됩니다.
이해를 돕기 위해 아래 이미지를 추가했습니다.
프로그래밍 언어를 목적 파일(오브젝트 파일 obj) 파일로 만드는 과정을 컴파일 과정이라고 부릅니다. 컴파일의 결과로 만들어진 목적 파일과 다른 목적 파일, 그리고 라이브러리 파일이 한 데 모여 실행 파일(Windows OS에서는 exe 등)이 되는 과정을 링크 과정이라 부릅니다. 현대에 들어서는 컴파일과 링크라는 단어를 따로 사용하기보다는 빌드(초기, MS가 Visual Studio를 앞세워 일인자가 된 후에는 다른 기업의 프로그램에서도 빌드라는 단어를 사용한다고 합니다)라는 단어를 사용하거나 컴파일이 링크의 의미를 포함하게 되었습니다. 엄연히 다른 의미를 가진 단어임은 알아두세요
아무튼, 이러한 과정 이전에 한가지가 더 있습니다. 바로 전처리 작업입니다.
우리가 어떤 작업을 할 때는 그 작업을 하기에 알맞은 환경을 조성합니다. 필요한 물건을 가져온다던가, 주변을 정리한다던가. IDE 또한 마찬가지로 빌드를 진행하기 전에 빌드에 알맞은 환경을 조성하기 위한 작업을 이 전처리 작업에서 한다고 생각하시면 편합니다.
코드에 컴파일러가 알아두어야 할 내용들을 작성해 두었다면, 예컨데 아래와 같은 코드를 작성했다면 이 코드는 컴파일 타임(컴파일하는 시간)에 작업하지 않고, 전처리타임에서 작업합니다. 아래 예시된 코드는 모두 컴파일러에게 어떤 행위를 명령하는 겁니다.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
// 익숙하시죠?
이 뿐만 아니라, 상수를 지정할 수도 있습니다.
#define MAX_NUM 10
그리고 매크로 함수도 작성할 수 있습니다.
#define ABS(X) ( 0 < (X) ? (X) : -(X) )
의외로 다양하게 사용할 수 있습니다.
typedef
type define의 약자로, 타입을 재정의 할 때 사용합니다. 프로그램을 작성하다 보면, 같은 자료형을 사용하지만 의미적으로 다른 데이터들이 있습니다. 나이와 키(cm)를 예로 들 수 있겠네요. 둘 모두 unsigned char로 표현할 수 있지만, 어느 하나의 데이터 자료형을 바꾸어야 한다면 어떻게 해야 할까요? 일일이 찾아 바꿔야 합니다. 이 과정에서 변경하지 못한 자료형이 있을 수 있고 이로 인해 잠재적 위험도가 높아지겠네요.
그래서 typedef 키워드가 존재합니다. typedef는 이미 존재하는 자료형을 통해 새로운 자료형을 재정의할 수 있습니다.
typedef unsigned char AGE
typedef unsigned char HEIGHT
이 상황에서, 나이의 자료형을 변경하고 싶다면 AGE가 재정의 된 typedef unsigned char AGE의 unsigned char 부분만 다른 것으로 변경해주면 됩니다.
자세한 설명은 아래 문서를 참고하세요
define VS typedef
가끔 타입 재정의를 typedef가 아니라 define을 이용해 하는 경우가 있습니다. 대부분 생각대로 동작하지만, 이는 좋지 않은 습관입니다. 다음 EX1 코드를 보겠습니다. EX1 코드는 define 전처리 지시자로 unsigned char의 포인터를 AGE 라는 자료형을 재정의한 것입니다.
// EX1
#define AGE unsigned char *
int main(void){
AGE a1, a2;
return 0;
}
본 목적은 a1과 a2의 자료형을 unsigned char *로 작성하고자 함입니다. 일반적으로 자료형을 작성한 후 ' , ' 연산자를 이용해 변수를 추가 선언하면 앞서 선언된 자료형을 따라갑니다. 즉, 아래 코드에서
SOMETYPE var1, var2;
var1 과 var2 변수는 SOMETYPE이라는 자료형으로 동일해야합니다. 그러나 예시로 설명드린 EX1 코드는 a1 변수와 a2 변수의 자료형이 서로 다릅니다. 이는, 앞서 설면드렸던 [전처리-컴파일-링크]의 특성 때문입니다.
즉, 전처리 작업은 치환을 하는 것이라고 보면 쉽습니다. <Ctrl + H>를 통해 바꾸기 기능에서 모두 바꾸기 기능과 유사한 것이라고 보면 됩니다.
원래 생각한대로 처리하려면 위 EX1 코드의 전처리 지시자로 작성했던 것을 아래와 같이 수정해야합니다.
typedef unsigned char * AGE
결국, typedef로 작성한 코드와 define으로 작성한 코드는 아래와 같이 된다고 보시면 되겠습니다.
// define으로 정의
#define AGE unsigned char *
int main(void){
AGE a1, a2;
return 0;
}
// ↓ 컴파일시 의미하는 코드
int main(void){
unsigned char * a1, a2;
return 0;
}
// typedef로 정의
typedef unsigned char * AGE
int main(void){
AGE a1, a2;
return 0;
}
// ↓ 컴파일시 의미하는 코드
int main(void){
unsigned char * a1, * a2;
return 0;
}
존재하는 대부분은 저마다 쓰임이 있습니다. 우리가 밥을 먹을 때, 젓가락을 사용하지 연필을 사용하지는 않는 것과 같은 이치입니다.
읽을 거리
define 전처리 지시자로 매크로 함수를 작성할 때 발생하는 문제점을 짚었습니다.
# index
'DEV > C C++' 카테고리의 다른 글
sizeof 연산자 (0) | 2019.06.17 |
---|---|
Snake with Windows API (0) | 2019.06.08 |
scanf_s 사용하기 (2) | 2019.04.28 |
배열 선언을 x-y가 아니라 y-x순으로 작성하는 이유 (4) | 2019.04.24 |
상수의 접미어 (0) | 2019.04.13 |