Czy typedef i # define są takie same w c?

Zastanawiam się czy typedef i #definesą takie same w c ?

Author: jww, 2009-11-03

9 answers

Nie.

#define jest tokenem preprocesora: sam kompilator nigdy go nie zobaczy.
typedef jest tokenem kompilatora: preprocesor nie dba o to.

Możesz użyć jednego lub drugiego, aby osiągnąć ten sam efekt, ale lepiej użyć odpowiedniego dla swoich potrzeb

#define MY_TYPE int
typedef int My_Type;

Kiedy rzeczy stają się" Owłosione", użycie odpowiedniego narzędzia sprawia, że jest dobrze

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

void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */
 101
Author: pmg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-03 10:07:43

typedef przestrzega reguł przeszukiwania tak jak zmienne, podczas gdy define zachowuje ważność do końca pliku (lub do dopasowania undef).

Również pewne rzeczy można zrobić z typedef, których nie można zrobić z define.

Przykłady:

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

#define int_p2 int*
int_p2 a, b, c;  // only the first is a pointer!

.

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
 205
Author: Andreas Grech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-03 10:03:05

Nie, Nie są takie same. Na przykład:

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

Po wstępnym przetworzeniu linia ta rozszerza się do

int* a, b;

Mam nadzieję, że widzisz problem; tylko a będzie miał typ int *; b zostanie zadeklarowany jako zwykły int (ponieważ {[8] } jest skojarzony z deklaratorem, a nie ze specyfikatorem typu).

Kontrast z

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

W tym przypadku zarówno a jak i b będą miały typ int *.

Są całe klasy typedefów, które nie mogą być emulowane za pomocą makra preprocesora, takiego jak wskaźniki do funkcji lub tablic:

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

Spróbuj to zrobić z makrem preprocesora.

 21
Author: John Bode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-03 15:52:49

#define definiuje makra.
typedef definiuje typy.

Oto kilka różnic:

Z # define można zdefiniować stałe, które mogą być używane w czasie kompilacji. Stałe mogą być używane z # ifdef do sprawdzania, jak kod jest kompilowany i specjalizowania określonego kodu zgodnie z parametrami kompilacji.
Możesz również użyć #define do zadeklarowania miniaturowego find-and-replace Makro funkcje.

Typedef może być używany do nadawania aliasów typom (co prawdopodobnie można zrobić również za pomocą #define), ale jest to bezpieczniejsze ze względu na naturę find-and-replace stałych #define.
Poza tym możesz użyć deklaracja terminowa z typedef, który pozwala zadeklarować typ, który będzie używany, ale nie jest jeszcze połączony z plikiem, w którym piszesz.

 10
Author: Yochai Timmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-11 19:31:37

Makra preprocesora ("#define 's") są leksykalnym narzędziem zastępczym a la "search and replace". Są całkowicie agnostyczni wobec języka programowania i nie rozumieją, co próbujesz zrobić. Możesz myśleć o nich jako o gloryfikowanej mechanice kopiowania/wklejania-czasami jest to przydatne, ale powinieneś używać go ostrożnie.

Typedefs to funkcja języka C, która umożliwia tworzenie aliasów dla typów. Jest to niezwykle przydatne do tworzenia skomplikowanych typów złożonych (takich jak struktury i funkcje pointers) czytelny i podręczny (w C++ są nawet sytuacje, w których musisz wpisać Typ).

For (3): zawsze powinieneś preferować funkcje języka niż makra preprocesora, gdy jest to możliwe! Dlatego zawsze używaj typedefs dla typów, a wartości stałych dla stałych. W ten sposób kompilator może faktycznie współdziałać z Tobą w znaczący sposób. Pamiętaj, że kompilator jest twoim przyjacielem, więc powinieneś powiedzieć mu jak najwięcej. Makra preprocesora robią dokładnie odwrotnie przez ukrywanie Twojej semantyki przed kompilatorem.

 4
Author: Kerrek SB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-30 16:56:33

Są bardzo różne, chociaż często są używane do implementacji niestandardowych typów danych(co zakładam, że chodzi o to pytanie).

Jak wspomniał pmg, {[1] } jest obsługiwane przez pre-procesor (jak operacja cut-and-paste) zanim kompilator zobaczy kod, a {[2] } jest interpretowany przez kompilator.

Jedną z głównych różnic (przynajmniej jeśli chodzi o definiowanie typów danych)jest to, że typedef pozwala na bardziej szczegółowe sprawdzanie typów. Na przykład,

#define defType int
typedef int tdType

defType x;
tdType y;

Tutaj kompilator widzi zmienną x jako int, ale zmienną y jako typ danych o nazwie 'tdType', który ma taki sam rozmiar jak int. Jeśli napisałeś funkcję, która przyjęła parametr typu defType, wywołujący mógłby przekazać normalną wartość int i kompilator nie wiedziałby różnicy. Gdyby funkcja zamiast tego przyjmowała parametr typu tdType, kompilator upewniłby się, że zmienna odpowiedniego typu została użyta podczas wywołania funkcji.

Również niektóre debuggery mają możliwość obsługi typedef s, która może być znacznie bardziej użyteczna niż lista wszystkich typów niestandardowych jako ich podstawowych typów prymitywnych (tak jak byłoby, gdyby zamiast tego użyto #define).

 2
Author: bta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-03 19:20:03

AFAIK, Nie.

'typedef' pomaga skonfigurować "alias" do istniejącego typu danych. Dla np. typedef char chr;

#define jest dyrektywą preprocesora używaną do definiowania makr lub ogólnych podzbiorów wzorców. Dla np. # define MAX 100, zastępuje wszystkie wystąpienia MAX przez 100

 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-03 10:00:45

Nie.
typedef jest słowem kluczowym C, które tworzy alias dla typu.
#define jest instrukcją przed procesorem, która tworzy Zdarzenie zastępujące tekst przed kompilacją. Gdy kompilator dotrze do kodu, oryginalnego słowa "# defined " już nie ma. #define jest używany głównie dla makr i stałych globalnych.

 1
Author: Traveling Tech Guy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-03 10:08:02

Jak wszyscy mówili powyżej, nie są tacy sami. Większość odpowiedzi wskazuje, że typedef jest bardziej korzystna niż #define. Ale pozwól mi umieścić punkt plus #define :
gdy twój kod jest bardzo duży, rozrzucony po wielu plikach, lepiej jest użyć #define; pomaga to w czytelności-możesz po prostu wstępnie przetworzyć cały kod, aby zobaczyć rzeczywistą definicję typu zmiennej w miejscu jej deklaracji.

 0
Author: abcoep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-21 06:23:22