F.R.I.D.A.Y.

typedef 본문

DEV/C C++

typedef

F.R.I.D.A.Y. 2020. 1. 4. 22:32
반응형

네이버 사전

 C언어에는 typedef라 불리는 기존 자료형을 다시 정의하는 키워드가 존재합니다. 이 포스트에서는 이 typedef에 대해 알아봅니다.


나도 별명을 가지고 싶다

 변수는 다양한 이름으로 선언해서 프로그램의 핵심 중추로 작용합니다. 그때, 자료형들이 시샘이 났습니다. 그래서 데니스 리치[# C언어의 창시자입니다. 자세한 내용은 링크를 참고하세요.]는 불만을 해소해주고자 만든 키워드가 typedef라고 보시면 좋겠습니다.

int var1;
char var2;
double real1;

 변수를 선언하는 방법입니다. typedef 또한 마찬가지로 작성할 수 있습니다.

typedef int integer;

 이렇게 작성하면 int의 별명으로서 integer라는 자료형이 새롭게 구현[# 물론 기반은 int이지만]됩니다. 위에 typedef 코드를 작성했다면 이제 이렇게 작성할 수 있습니다.

int var1;
// 위 코드와 아래 코드는 같은 의미입니다.
integer var1;

typedef

 typedef는 기본적으로 아래와 같이 작성합니다.

typedef [기존 자료형] [새롭게 선언할 자료형];

 여기 기존 자료형에는 빌트인 자료형뿐만 아니라 사용자가 직접 만든 구조체나 배열, 유니온 등의 자료형 또한 작성할 수 있습니다.

 


구조체를 선언할 때

구조체 변수를 만들 때 귀찮게 struct를 함께 작성하지 않을 수 있습니다. typedef를 이용하면 가능한데요. 아래 예시를 보겠습니다.

// case 1 : struc A를 선언과 동시에 자료형 이름 새로 정의
typedef struct A{
    int va;
    int vb;
}A;

// case 2 : 익명 구조체를 선언과 동시에 자료형 이름 새로 정의
typedef struct{
    int va;
    int vb;
}A;

// case 3 : 구조체 선언후 typedef를 이용해 자료형 이름 새로 정의
struct A{
    int va;
    int vb;
};

typedef struct A A;

// case 4 : struct _a를 선언과 동시에 자료형 이름 새로 정의
typedef struct _a{
    int va;
    int vb;
}A;

 이렇게 네 개의 예시를 가져왔는데요. typedef를 앞에 작성하면 구조체를 미리 선언하지 않고도 바로 이어서 자료형의 이름을 새롭게 정의 내릴 수 있습니다.

 case 4의 경우에는 구조체 이름이 A로 통일되어있기 때문에 typdef로 정의 내릴 자료형의 이름[# 이전 설명에서 int]과 새롭게 정의 내릴 이름[# 이전 설명에서 integer]이 같아야 하지는 않을까?라는 고민을 가지실지 몰라 별개로 동작함을 알려드리기 위해 추가했습니다.

 구조체의 이름과 새롭게 정의 내리는 이름은 같을 필요가 없습니다. 이름이 같다면 struct를 빼는 것 외에 무슨 의미가 있을까요.

더보기

# 구조체 선언은 typedef 선언보다 더 높은 LifeCycle에서

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct _employee employee;

int main(void){
	
	struct _employee{
		int n;
		char name[10];
	};
	
	employee ex1;
	
	ex1.n = 10;
	strcpy(ex1.name, "hello");
	
	printf("%d %s", ex1.n, ex1.name);
	
	
	return 0;
}

 이 코드를 작성해서 컴파일 하면, 아래와 같이 에러 문구 리턴되면서 컴파일에 실패합니다.

 말인 즉, 저렇게 작성하면 main 함수에서 employee 타입으로 선언했을 때, typedef struct _employee로 타입을 찾아 올라갑니다. 그러나 여러 함수에서 struct _employee가 선언되어있다면 typdef에서 다시 struct _employee라는 구조체를 찾아갈 때 어느 함수의 구조체로 들어갈지 몰라 크기를 특정할 수 없게 됩니다. 그래서 typedef를 이용한 재정의는 구조체 선언보다 안쪽. 즉, LifeCycle이 짧게 존재해야합니다.

더보기

# 공용체 선언때도 이렇게 작성하면 됩니다.

 공용체와 구조체는 문법 작성 구조가 굉장히 유사합니다. struct를 입력했는지, union을 입력했는지에 따라서 메모리 관리/접근 방식에 차이가 발생하는 것이지 작성 방법은 똑같습니다.

 위에 예시로 보여드렸던 구조체 선언 방식에서 struct를 union으로만 변경하면 union에 대한 typedef 적용이 됩니다.


배열을 재정의하기

 int 자료형의 길이 100인 배열을 만들어보겠습니다.

int arr[100];

 이런 배열을 수십 개 만들었는데, 갑자기 길이를 150으로 늘려야 한다면 일일이 찾아 바꿔주어야 할 겁니다. 이럴 때도 typedef를 사용하면 쉽게 해결할 수 있습니다.

typedef int ARR[150];

ARR a1;

a1[0] = 5;

이렇게 하면 길이 150의 배열 자료형 ARR150이 생기고, 이 자료형을 이용해 만든 a1이라는 변수가 생깁니다. 사용은 배열처럼 자유롭게 하면 됩니다. 만일 필요하다면 typedef로 재정의해준 부분만 수정하면 되겠네요.


함수 포인터를 재정의하기

함수 포인터는 대체적으로 난해한 문법 중에 하나입니다.

void (*fp)(int);

 위 코드는 반환형이 없고 인자로 int 타입의 값을 하나 가지는 함수를 가리키는 포인터 변수 fp를 선언한 것입니다. 이런 변수를 한 번만 사용하면 좋겠지만, 대부분 여러 개를 함께 만들어 사용할 겁니다. 그럴 때 이렇게 작성하면 편하게 작성할 수 있습니다.

typedef void (*fp_vi)(int);

 이렇게 작성하면 fp_vi라는 함수 포인터 자료형이 생성됩니다. 이제

fp_vi fp;

 이렇게 작성해 반환 타입이 없고 인자로 int 값 하나를 가지는 함수 포인터 변수 fp를 만들게 됩니다. 이 문법은 난해하지만 함수 포인터를 사용하면서 수정해야 할 부분이 많다면 충분히 사용가치가 존재합니다.

 심지어 길게 선언해야 하는 것을 짧게 줄일 수도 있죠.


그래서 왜 사용하나

 앞서 설명드린 것과 마찬가지로 편의성을 증대시키기 위해 사용합니다. 그러나 편의성 증대는 typedef의 주요 목표 중 하나에 불과합니다. 아래 코드를 보겠습니다.

void printAge(char age){
	printf("age : %d\n", (int)age);
}

void printDDay(char dDay){
	printf("D-%d\n", (int)dDay);
}

int main(void){
    char age;
    age = 15;
    char dDay;
    dDay = 100;
    
    printAge(age);
}

 120살을 넘지 않는다고 가정하고 나이에는 char을, D-Day 또한 그리 길지 않을 것이라 생각하고 char 타입으로 선언했습니다. D-Day가 갑자기 200일을 넘겼다고 가정합니다. 어떻게 변경하겠습니까?

 IDE에서 제공하는 일괄 변경 기능을 사용해도 되고, 하나씩 찾아가면서 바꿔도 될겁니다. 그런데 일괄 변경은 age 또한 char 타입을 사용하고 있어서 나이 자료형도 함께 변경될 것입니다. 하나씩 찾아가면서 일일이 바꾸는 것은 시간이 오래 걸립니다.

 

 그래서 typedef를 사용합니다. 각각의 데이터가 의미하는 자료형으로 분리하기 위해서.

typedef char DDAY;
typedef char AGE;

 이렇게 두 줄만 작성하고 이후에 변수에 알맞은 자료형만 작성해 넣어주었다면 범위를 바꾸어야 할 때 손쉽게 저 두 줄의 코드만 변경하면 되었을 것입니다.

 결국 typedef는 아래의 목적으로 이용하게 되는 것입니다.

  • 긴 선언을 짧게 줄임
  • 자료형을 분리하여 코드 유지/보수 능률 향상
  • 이해하기 쉬운 코드 작성[# 자료형-변수명의 순을 정확히 정하게 할 수 있어 변수가 무슨타입인지 이해를 돕습니다. 만일 이해가 되지 않는다면 이 포스트를 참고하세요.]

# index

728x90
반응형
Comments