본문 바로가기
Language&Framework&Etc/C

구조체와 사용자 정의 자료형2(23-1) 구조체의 정의와 typedef 선언

by 머리올리자 2020. 12. 13.

구조체 변수를 선언할 때에는 무조건 struct 선언을 추가해야 한다.

하지만 이런 것들이 귀찮음

int형 변수 num을 선언할 때 그저 int num이라고 선언하듯이,

person형 구조체 변수 man을 선언할 때에도 struct 선언 없이 그저 person man이라 하고 싶다.

 

그렇다면 구조체를 정의한 후에 typedef 선언을 추가해야 함

typedef 선언

typedef 선언은 기존에 존재하는 자료형의 이름에 새 이름으로 부여하는 것을 목적으로 하는 선언

 

typedef int INT; // int의 또 다른 이름 INT를 부여!

이로 인해 다음의 뜻을 컴파일러에게 전달

 

"자료형의 이름 int에 INT라는 이름의 추가로 붙여준다"

 

다음의 형태로 int형 변수를 선언할 수 있음

INT num; // int num; 과 동일한 선언

int형 포인터 변수 선언도 가능

INT* ptr; // int ptr; 과 동일한 선언

 

예제

#include <stdio.h>

typedef int INT;
typedef int* PTR_INT;

typedef unsigned int UINT;
typedef unsigned int* PTR_UINT;

typedef unsigned char UCHAR;
typedef unsigned char* PTR_UCHAR;

int main(void)
{
	INT num1 = 120;
	PTR_INT pnum1 = &num1;

	UINT num2 = 190;
	PTR_UINT pnum2 = &num2;

	UCHAR ch = 'Z';
	PTR_UCHAR pch = &ch;

	printf("%d, %u, %c \n", *pnum1, *pnum2, *pch);
	return 0;
}

typedef 선언에 있어서 새로운 이름의 부여는 가장 마지막에 등장하는 단어를 중심으로 이뤄진다.

 

즉, 다음의 형태로 typedef가 선언되면,

typedef name1 name2 name3;

가장 마지막에 등장한 name3가 'name1 name2'에 부여된 새로운 이름이 되는 것임.

 

따라서 새롭게 부여된 이름과 그 대상이 되는 자료형은 다음과 같다.

 

새로 부여된 이름 대상 자료형
INT int
PTR_INT int*
UINT unsigned int
PTR_UINT unsigned int*
UCHAR unsigned char
PTR_UCHAR unsigned char*

위 예제에서 보이듯이 typedef 선언을 통해서, 복잡한 유형의 자료형 선언을 매우 간결히 처리할 수 있다.

 

typedef로 정의되는 자료형의 이름은 대문자로 시작하는 것이 관례(기본 자료형의 이름과 typedef로 새로이 정의된 자료형의 이름을 구분할 수 있기 때문)

 

구조체의 정의와 typedef 선언

구조체에도 typedef 선언을 할 수 있음

struct point
{
	int xpos;
	int ypos;
};

다음과 같이 구조체 변수를 선언해야 함

struct point pos;

다음과 같이 typedef 선언이 이뤄지고 나면

typedef struct point Point; // struct point에 Point라는 이름을 부여!

struct point를 대신할 수 있도록 Point라는 이름을 정의한 셈이니, 이후로는 다음과 같이 struct 선언을 생략한 형태로 구조체 변수를 선언할 수 있음.

Point pos;

"대부분의 경우, 구조체 정의의 뒤를 이어서 typedef 선언이 등장"

 

모든 구조체의 이름을 대상으로 struct 선언의 생략을 위한 typedef 선언이 등장.

 

표현 방법 1.

struct point
{
	int xpos;
	int ypos;
};
typedef struct point Point;

위 정의와 선언을 하나로 묶으면

 

표현 방법 2.

typedef struct point
{
	int xpos;
	int ypos;
}Point;

 

예제

#include <stdio.h>

struct point
{
	int xpos;
	int ypos;
};

typedef struct point Point;

typedef struct person
{
	char name[20];
	char phonenum[20];
	int age;
} Person;

int main(void)
{
	Point pos = { 10, 20 };
	Person man = { "하이맨", "010-1234-5678", 1500 };
	printf("%d %d \n", pos.xpos, pos.ypos);
	printf("%s %s %d \n", man.name, man.phonenum, man.age);

	return 0;
}

typedef 선언이 추가되었다고 struct 선언을 통한 구조체 변수의 선언이 불가능한 것은 아니다.

 

즉, 다음과 같이 구조체가 정의되면

typedef struct point
{
	int xpos;
	int ypos;
}Point;

다음 두 가지 방식으로 구조체 변수 선언

Point pos1;        // typedef 선언을 이용한 변수의 선언 OK!
struct point pos2; // struct 선언을 추가한 형태의 변수선언 OK!

 

구조체의 이름

 

다음과 같이 simple이라는 이름의 구조체가 정의되고 sosomple이라는 이름이 정의되면

typedef struct simple
{
	....
}SoSimple;

위의 구조체를 가리켜 simple 구조체라 부르기도 하고, SoSimple 구조체라 부르기도 한다.

어떻게 부르건 상관없다.

하지만 typedef로 정의된 이름으로 해당 구조체를 가리키는 것이 보다 일반적이다.

 

구조체의 이름 생략

typedef struct person
{
	char name[20];
	char phonenum[20];
	int age;
} Person;

위와 같이 정의하면 구조체 이름 person은 사실상 별 의미를 갖지 않게 된다.

 

구조체 변수를 선언할 때도 typedef에 의해 정의된 이름 Person을 사용하기 때문이다.

 

따라서 다음과 같이 구조체의 이름을 생략 가능

typedef struct
{
	char name[20];
	char phonenum[20];
	int age;
} Person;

이렇게 하면 다음의 형태로 구조체 변수를 선언할 수 없음

struct person man; // 불가능한 선언!

typedef 선언은 구조체 선언을 조금 편하게 하기 위함인데 위에 처럼 굳이 struct 선언까지 하면서 변수를 선언할 필요가 없음.

 

구조체의 이름을 생략하는 경우도 흔하다.

 

참고 : [윤성우 열혈 C 프로그래밍] - 대부분의 내용 및 코드는 이 책에서 개인 공부 정리 목적으로 참고하였습니다.