typedef와 #define은 c에서 동일합니까?


답변:


122

아니.

#define전 처리기 토큰입니다 : 컴파일러 자체는 그것을 볼 수 없습니다.
typedef컴파일러 토큰입니다. 전처리 기는 신경 쓰지 않습니다.

둘 중 하나를 사용하여 동일한 효과를 얻을 수 있지만 필요에 따라 적절한 것을 사용하는 것이 좋습니다.

#define MY_TYPE int
typedef int My_Type;

일이 "털이 많을"때 적절한 도구를 사용하면 제대로 작동합니다.

#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);

void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */

3
typedef 다음 stdfx에 해당 유형의 유효한 객체는 int를 받고 값을 반환하지 않는 함수에 대한 포인터입니다.
pmg

1
함수 포인터의 casec에서 #define이 인수로 실패하는 이유는 무엇입니까?
Allahjane

2
@Allahjane : 확장이됩니다 void fx_def(void (*)(int) fx);; 올바른 선언은 void fx_def(void (*fx)(int));입니다.
pmg

5
함수 포인터는 구문을 포기할 준비가 된 경우에만 매크로로 수행 할 수 #define FX_TYPE(f) void (*f)(int)있습니다.. 그런 다음 함수를 다음과 같이 선언합니다.void fx_def(FX_TYPE(fx));
plafer

229

typedef변수와 마찬가지로 범위 지정 규칙을 준수하는 반면 define컴파일 단위가 끝날 때까지 (또는 일치하는 undef) 까지 유효합니다 .

또한으로 수행 typedef할 수없는 일부 작업을 수행 할 수 있습니다 define.
예를 들면 :

typedef int* int_p1;
int_p1 a, b, c;  // a, b, c are all int pointers

#define int_p2 int*
int_p2 a, b, c;  // only the first is a pointer, because int_p2
                 // is replaced with int*, producing: int* a, b, c
                 // which should be read as: int *a, b, c
typedef int a10[10];
a10 a, b, c;  // create three 10-int arrays
typedef int (*func_p) (int);
func_p fp;  // func_p is a pointer to a function that
            // takes an int and returns an int

23

아니요, 동일하지 않습니다. 예를 들면 :

#define INTPTR int*
...
INTPTR a, b;

전처리 후 해당 줄은 다음으로 확장됩니다.

int* a, b;

문제가 보이길 바랍니다. 단지 a유형이있을 것이다 int *; b일반으로 선언됩니다 int( *는 유형 지정자가 아닌 선언자와 연결되어 있기 때문 입니다).

그것과 대조

typedef int *INTPTR;
...
INTPTR a, b;

이 경우, 모두 ab유형이있을 것이다 int *.

함수 또는 배열에 대한 포인터와 같이 전 처리기 매크로로 에뮬레이션 할 수없는 typedef의 전체 클래스가 있습니다.

typedef int (*CALLBACK)(void);
typedef int *(*(*OBNOXIOUSFUNC)(void))[20]; 
...
CALLBACK aCallbackFunc;        // aCallbackFunc is a pointer to a function 
                               // returning int
OBNOXIOUSFUNC anObnoxiousFunc; // anObnoxiousFunc is a pointer to a function
                               // returning a pointer to a 20-element array
                               // of pointers to int

전 처리기 매크로를 사용해보십시오.


13

#define 은 매크로를 정의합니다.
typedef 는 유형을 정의합니다.

이제 몇 가지 차이점이 있습니다.

#define 을 사용하면 컴파일 타임에 사용할 수있는 상수를 정의 할 수 있습니다. 상수는 #ifdef 와 함께 사용 하여 코드가 어떻게 컴파일되는지 확인하고 컴파일 매개 변수에 따라 특정 코드를 특수화 할 수 있습니다. #define
사용 하여 미니어처 찾기 및 바꾸기 매크로 함수 를 선언 할 수도 있습니다 .

typedef 를 사용하여 유형에 별칭을 제공 할 수 있지만 ( #define 으로도 수행 할 수 있음 ) #define 상수 의 찾기 및 바꾸기 특성 때문에 더 안전 합니다.
그 외에도 사용할 유형을 선언 할 수 있지만 아직 작성중인 파일에 연결되지 않은 typedef 와 함께 포워드 선언 을 사용할 수 있습니다 .


#define의 특성을 찾고 바꾸는 것은 무엇을 의미합니까? , 감사합니다
Mohamed El Shenawy 2015-06-07

1
그것은 컴파일하기 전에 의미, 전처리 모든 매크로를 찾아 원래 구문으로 대체합니다
왕자 비제이 프라 탑

"typedef는 유형에 별칭을 부여하는 데 사용할 수 있습니다."이것은 저에게 목적을 설명했습니다. 감사합니다.
Dave Voyles

8

전 처리기 매크로 ( " #define's")는 "검색 및 바꾸기"라는 어휘 대체 도구입니다. 그들은 프로그래밍 언어에 전적으로 무관하며 당신이하려는 일을 이해하지 못합니다. 당신은 그것들을 영광스러운 복사 / 붙여 넣기 메커니즘으로 생각할 수 있습니다. 때로는 유용하지만주의해서 사용해야합니다.

Typedef는 유형에 대한 별칭을 만들 수있는 C 언어 기능입니다. 이것은 복잡한 복합 유형 (구조체 및 함수 포인터와 같은)을 읽기 쉽고 다루기 쉽게 만드는 데 매우 유용합니다 (C ++에서는 유형을 typedef 해야하는 상황도 있습니다 ).

(3)의 경우 : 가능하면 항상 전 처리기 매크로보다 언어 기능을 선호해야합니다! 따라서 항상 유형에는 typedef를 사용하고 상수에는 상수 값을 사용하십시오. 이렇게하면 컴파일러가 실제로 사용자와 의미있게 상호 작용할 수 있습니다. 컴파일러는 당신의 친구이므로 가능한 한 많이 말해야합니다. 전 처리기 매크로는 컴파일러에서 의미를 숨기는 방식으로 정반대를 수행합니다 .


유형을 typedef해야하는 C ++의 한 예를 말할 수 있습니까? 나는 그것에 대해 단지 궁금합니다.
jyz 2015

@jyzuz : 멤버 함수가 함수 포인터의 배열을 반환하도록하려면 무언가가 있습니다. 또는 이와 비슷한 것이 있습니다. 유형을 철자하려고하면 GCC는 실제로 "typedef를 사용해야합니다"라고 말합니다.
Kerrek SB 2013

4

사용자 지정 데이터 유형을 구현하는 데 자주 사용되지만 매우 다릅니다 (이 질문이 전부라고 가정합니다).

pmg가 언급했듯이 #define컴파일러가 코드를보기 전에 사전 처리기 (예 : 잘라 내기 및 붙여 넣기 작업)에 typedef의해 처리되고 컴파일러에 의해 해석됩니다.

(적어도 데이터 유형을 정의 할 때) 주요 차이점 중 하나는 typedef보다 구체적인 유형 검사 를 허용 한다는 것 입니다. 예를 들면

#define defType int
typedef int tdType

defType x;
tdType y;

여기서 컴파일러는 변수 x를 int로 인식하지만 변수 y는 int와 크기가 같은 'tdType'이라는 데이터 유형으로 간주합니다. defType 유형의 매개 변수를 사용하는 함수를 작성한 경우 호출자는 일반 int를 전달할 수 있으며 컴파일러는 차이를 알 수 없습니다. 대신 함수가 tdType 유형의 매개 변수를 사용하는 경우 컴파일러는 함수 호출 중에 적절한 유형의 변수가 사용되었는지 확인합니다.

또한 일부 디버거는 typedef s . 이는 모든 사용자 정의 유형을 기본 기본 유형으로 나열하는 것보다 훨씬 유용 할 수 있습니다 ( #define대신 사용 된 경우).


2

아니요.
typedef 는 유형에 대한 별칭을 만드는 C 키워드입니다.
#define은 컴파일 전에 텍스트 대체 이벤트를 생성하는 전 처리기 명령어입니다. 컴파일러가 코드에 도달하면 원래 "#defined"단어가 더 이상 존재하지 않습니다. #define은 주로 매크로 및 전역 상수에 사용됩니다.


2
"포인터"라는 용어의 사용은 여기서 약간의 혼란을 야기 할 수 있습니다.

동의합니다. 이것이 내가 돌아가서 MSDN의 typdef에 대한 링크를 추가 한 이유입니다. 미래에 누군가가이 질문을 사용하여 typedef가 무엇인지 찾을 경우를 대비하여. 하지만 그 단어를 바꿔야 할 수도 있습니다 ...
Traveling Tech Guy

2

AFAIK, 아니요.

typedef기존 데이터 유형에 대한 "별칭"을 설정하는 데 도움이됩니다. 예를 들어. typedef char chr;

#defineA는 전 처리기 매크로 또는 일반 패턴 대체를 정의하는 데 사용 지침은. 예를 들어. #define MAX 100, 모든 항목을 MAX100으로 대체


0

위에서 언급했듯이 #define 및 typedef 있습니다. 이에 대해 생각하는 올바른 방법은 typedef를 완전한 "캡슐화 된"유형으로 보는 것입니다. 선언 한 후에는 추가 할 수 없음을 의미합니다.

다른 유형 지정자를 사용하여 매크로 유형 이름을 확장 할 수 있지만 typedef의 유형 이름은 확장 할 수 없습니다.

#define fruit int
unsigned fruit i;   // works fine

typedef int fruit;
unsigned fruit i;   // illegal

또한 typedef의 이름은 선언의 모든 declator에 대한 유형을 제공합니다.

#define fruit int *
fruit apple, banana;

매크로 확장 후 두 번째 줄은 다음과 같습니다.

int *apple, banana;

Apple은 int에 대한 포인터이고 banana는 int입니다. 비교하면. 다음과 같은 typedef :

typedef char *fruit;
fruit apple, banana;

사과와 바나나가 동일하다고 선언합니다. 앞면의 이름은 다르지만 둘 다 문자에 대한 포인터입니다.


-1

모두가 위에서 말했듯이 그들은 동일하지 않습니다. 답변의 대부분은 표시 typedef보다 더 유리한 것으로 #define. 하지만 플러스 포인트를 두겠습니다 #define.
코드가 매우 크고 많은 파일에 흩어져있는 경우 사용하는 것이 좋습니다 #define. 가독성을 높이는 데 도움이됩니다. 모든 코드를 전처리하기 만하면 선언 자체에서 변수의 실제 유형 정의를 볼 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.