먼저 typedef와 struct 지시어에 대해 먼저 논해보자.
<typedef>
typedef unsigned int UINT
// 이 구문은 unsigned int의 자료형을 UINT로 쓰겠다는 의미임
.
.
unsigned int i;
UINT i;
//위의 두 선언을 같은 결과를 가져온다.
함수 포인터의 재정의로도 사용된다.
typedef int (*funcptr) ();
//funcptr을 리턴값이 int이고,매개인자가 없는 함수포인터로 선언
.
.
funcptr myfunction[10];
int (*myfunction[10])();
//같은 결과를 가져옴..
<struct>
struct MY_struct {
int a;
int b;
};
//구조체 선언을 나타내는 지시어 struct, MY_struct는 구조체의 이름.
// a, b는 멤버 데이터이며, 이를 묶어주는 중괄호로 구성되며, 구조체 선언끝에 ;를 명시
함수의 선언에서 {}의 의미는 메인메모리로 부터 스택영역을 할당받는 역할을 수행하지만, 구조체 선언에서 사용되는 {}는 메인메모리에 아무런 영향을 미치지 않는다. 따라서 후자를 구분하기 위해 ;를 구조체 선언끝에 명시한다.
구조체의 객체 생성은 다음과 같다.
1.
struct MY_struct {
int a;
int b;
};
struct MY_struct A1, *pA2;
//C compiler에서는 객체 생성시 struct지시어를 반드시 명기해야 하고, C++ compiler에서는 생략해도 C++ complier가 알아서 My_struct를 사용자 정의 데이터형으로 인식하여 객체를 선언해줌.
//좀더 자세히 설명하면, C complier는 변수선언이 가능한 키워드(int , char , float ,void 등)로만 시작할때 변수선언이 가능합니다. 사용자 정의 변수형(enum, union, struct)의 경우 그냥 선언한 이름만 사용할 경우 컴파일러는 변수 선언을 인식하지 못한다. 따라서 C complier에게 사용자 정의 변수형이라는 것을 알려주기 위해 사용자 정의 변수형 이름앞에 지시어를 적어줘야 함.
// 구조체의 객체중 A1은 정적 객체로 선언, pA2는 포인터 객체로 선언.
2.
struct MY_struct {
int a;
int b;
}A1, *pA2;
이상으로 간단하게 typedef와 struct 지시어에 대해 간단히 알아보았다.
그럼 이제 본격적으로 typedef와 struct를 같이 사용할때의 경우를 알아보자.
앞에서도 언급했지만, 사용자 정의 데이터형을 선언할때 매번 지시어(enum, struct, union)를 적어주는 일은 많이 번거롭다. C complier에서는 사용자 정의 타입 이름도 typedef로 재정의가 가능하게 허용하였다.
typedef를 사용하여 재정의한 사용자 정의 데이터형의 예를 보면,.....
typedef struct __MY_struct{
int a;
int b;
}MY_struct, *pMY_struct;
//이 구문에서 __MY_struct는 구조체의 이름, a, b는 맴버 데이터, MY_struct와 *pMY_struct는 선언한 구조체를 정의한 데이형을 MY_struct와 *pMY_struct로 제선언.
.
.
1.
struct __MY_struct A1, *pA2;
2.
MY_struct A1;
pMY_struct pA2;
//1에서 선언한 것과 2에서 선언한 것은 같은 결과를 가져온다.
//2처럼 사용할 경우 앞에 struct라는 지시어를 사용하지 않고 바로 사용 가능
//보통 C에서는 이런식으로 사용하기 때문에 구조체의 이름은 잘 사용하지 않는 이름으로 정의하고 재정의되는 이름을 알아보기 편한 이름으로 정의한다.
참고적으로, 위에서 선언한 경우는 정석적인 사용이며, 오사용및 변칙사용의 예를 들어 들어 보면....
1.
typedef struct {
int a;
int b;
}MY;
2.
struct MY{
int a;
int b;
};
3.
typedef struct MY{
int a;
int b;
};
1과 2의 경우는 C++ 에서는 같은 동작을 합니다. 하지만, C에서는 다름 결과를 냅니다.
1에서는 이름없는 구조체가 생성이 되고, 그 구조체를 사용하기 위한 새로운 자료형이름으로 MY가 등록이 됩니다.
2에서는 단지 MY라는 구조체가 생성이됩니다.
따라서 C에서는 다음과 같이 사용해야 합니다.
<1의 경우>
MY A1;
<2의 경우>
struct MY A1;
3의 경우는 에러 발생(경우에 따라서는 warning만 뜬다고 합니다.) 사용자의 의도와는 다른 방향으로 컴파일 됩니다.
typedef의 경우는 두개의 인자가 필요합니다. 앞의 인자는 컴파일러가 기존에 알고있는 지시어, 뒤에있는 인자는 사용자가 새롭게 정의할 이름입니다.
3의 경우는 2번째 인자가 없는 형태이므로 에러가 발생하거나, 그냥 구조체의 이름이 MY인 구조체만 생성하게 됩니다.
-이상-
[출처]typedef & struct|작성자kri7001
1. typedef 키워드
- 구조체는 분명히 자료형 입니다.
하지만 우리는 평소에 구조체를 선언해 줄 때 struct ~~~~ , struct ~~~~를 계속 적어주었습니다.
int자료형은 int만 적어주면 되는데, 왜 구조체는 struct를 써 줘야 하는 걸까요?
이럴 경우 소스에 오타가 발생할 경우가 생기고,
또한 귀찮기도 하고, 가독성에도 약간의 문제가 생깁니다.
따라서 이 struct를 없애 줄 수 있는 키워드가 바로 typedef키워드입니다.
typedef의 기본형은 이렇습니다.
typedef double DOUBLE
이것이 무엇을 의미하는 것이냐면
double이라는 자료형에게 DOUBLE이라는 새로운 이름을 지어주는 것입니다.
컴파일러에 실제로 DOUBLE을 쳐 보시면 double자료형으로 인식하지 못함을 알 수 있는데요.
이 문구만 적어주면 DOUBLE도 double자료형으로 인식하게 만들어 줄 수 있습니다.
즉
DOUBLE i=90.2;
따위의 선언이 가능하다는 말이지요.
쉽게 말해서 '컴파일러야~! 이것을~(double) 이것으로(DOUBLE)로 생각하려무나(typedef)'
로 정리해 볼 수 있습니다.
정말 완벽한 문장이네요.
[만약에 일반공부처럼 C언어공부도 개념정리노트를 만든다고 한다면
이 문장은 별표 3개 붙이고 색깔 분류해놓고 적어놓고 싶네요.]
이 문장에서 정의한 것을 토대로 한번 구조체도 이런 형식으로 만들어 보겠습니다.
typedefstruct pointer pointer;
'컴파일러야~! struct pointer를 pointer로 생각하려무나'
로 사용할 수 있겠습니다.
또한 이 방법 외에도
typedef struct pointer
{
int i ......
int z.......
}pointer;
형식으로도 제시해 줄 수 있습니다.
[출처][베리군의C강좌] 19. 구조체 - (5) struct를 지워보자.|작성자베리군
typedef struct 를 쓰는 이유는
자료명 사용의 용이성(?) 이라고 볼수 있죠
예를 들어 struct card 를 만들었을경우 이 구조형을 쓸때마다
struct card 라고 해줘야 하는 반면
이것을 typedef struct card {..... } CARD 로 선언했을경우
CARD 라고만 해주면 되기 때문이죠
언어 표준만을 지원하는 컴파일러는 위와 같은 구문은 컴파일시 에러나 워닝을 냅니다. 그래서 그와 같은 컴파일러에서는 구조체를 typedef로 새 타입이름으로 선언하더라도, 임시로 사용할 태그 이름이 필요하게 됩니다. 따라서, 이와 같은 컴파일러에서는 다음과 같이 임시 태그 이름을 사용하여 typedef로 타입 이름을 선언해야 합니다. (물론, 번거롭긴 하지만 표준과 일치하는 방법입니다.)
typedef struct _tagPoint{
int x;
int y;
}POINT;
이와 같은 구문은, 어떤 컴파일러를 쓰더라도 정확히 동일한 결과를 내므로 안전한 기법이라고 할 수 있겠습니다.
'Program C/C++' 카테고리의 다른 글
Class 내부 Thread basic... (1) | 2013.05.10 |
---|---|
c 표준 함수들 (0) | 2011.06.24 |
문자열 타입 변환 | C & C++ (0) | 2010.10.13 |
C++의 다양한 string 타입 | C & C++ (0) | 2010.01.30 |
About String (0) | 2005.08.05 |