Zastanawiam się, czy typedef
i #define
są takie same wdo?
124
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 robi się „owłosiona”, użycie odpowiedniego narzędzia naprawia to
#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);
void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */
stdfx
prawidłowe obiekty tego typu są wskaźnikami do funkcji, które otrzymują int i nie zwracają wartości.void fx_def(void (*)(int) fx);
; prawidłowa deklaracja tovoid fx_def(void (*fx)(int));
.#define FX_TYPE(f) void (*f)(int)
. Następnie zadeklarowałbyś swoją funkcję jako:void fx_def(FX_TYPE(fx));
typedef
przestrzega reguł określania zakresu tak samo jak zmienne, aledefine
pozostaje ważna do końca jednostki kompilacji (lub do dopasowaniaundef
).Ponadto można zrobić z
typedef
tym pewne rzeczy , których nie można zrobićdefine
.Na przykład:
źródło
Nie, to nie to samo. Na przykład:
Po wstępnym przetworzeniu ta linia rozwija się do
Miejmy nadzieję, że widzisz problem; tylko
a
będzie miał typint *
;b
zostanie zadeklarowany jako zwykłyint
(ponieważ*
jest skojarzony z deklaratorem, a nie specyfikatorem typu).Porównaj to z
W takim przypadku oba
a
ib
będą miały typint *
.Istnieją całe klasy typedef, których nie można emulować za pomocą makra preprocesora, na przykład wskaźniki do funkcji lub tablic:
Spróbuj to zrobić za pomocą makra preprocesora.
źródło
#define definiuje makra.
typedef definiuje typy.
Mówiąc to, oto kilka różnic:
Za pomocą #define możesz zdefiniować stałe, które mogą być używane w czasie kompilacji. Stałe mogą być używane z #ifdef, aby sprawdzić, jak kod jest kompilowany, i specjalizować określony kod zgodnie z parametrami kompilacji.
Możesz także użyć #define, aby zadeklarować miniaturowe funkcje makra znajdź i zamień .
typedef może służyć do nadawania aliasów typom (co prawdopodobnie można by zrobić również za pomocą #define ), ale jest to bezpieczniejsze ze względu na naturę #define typu znajdź i zamień .
Poza tym możesz użyć deklaracji forward z typedef, która pozwala zadeklarować typ, który będzie używany, ale nie jest jeszcze powiązany z plikiem, w którym piszesz.
źródło
Makra preprocesora („
#define
s”) są leksykalnym narzędziem zastępującym a la „wyszukaj i zamień”. Są całkowicie agnostykami języka programowania i nie rozumieją, co próbujesz zrobić. Możesz myśleć o nich jako o chwalebnym mechanizmie kopiowania / wklejania - czasami jest to przydatne, ale powinieneś używać go ostrożnie.Typedef to funkcja języka C, która umożliwia tworzenie aliasów dla typów. Jest to niezwykle przydatne, aby skomplikowane typy złożone (takie jak struktury i wskaźniki funkcji) były czytelne i obsługiwane (w C ++ są nawet sytuacje, w których trzeba wpisać typ).
Dla (3): Zawsze powinieneś preferować funkcje językowe od makr preprocesora, kiedy jest to możliwe! Dlatego zawsze używaj typedef dla typów i stałych wartości dla stałych. W ten sposób kompilator może faktycznie współdziałać z Tobą. Pamiętaj, że kompilator jest twoim przyjacielem, więc powinieneś mu powiedzieć jak najwięcej. Makra preprocesora działają dokładnie odwrotnie, ukrywając semantykę przed kompilatorem.
źródło
Są bardzo różne, chociaż często są używane do implementacji niestandardowych typów danych (i zakładam, że o to chodzi w tym pytaniu).
Jak wspomniano, pmg
#define
jest obsługiwany przez preprocesor (podobnie jak operacja wycinania i wklejania), zanim kompilator zobaczy kod, itypedef
jest interpretowany przez kompilator.Jedną z głównych różnic (przynajmniej jeśli chodzi o definiowanie typów danych) jest to, że
typedef
umożliwia bardziej szczegółowe sprawdzanie typów. Na przykład,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ęłaby parametr typu defType, wywołujący mógłby przekazać normalną wartość int, a kompilator nie znałby różnicy. Gdyby zamiast tego funkcja przyjęła parametr typu tdType, kompilator zapewni, że podczas wywołań funkcji zostanie użyta zmienna odpowiedniego typu.
Ponadto niektóre debugery mają możliwość obsługi
typedef
s, co może być znacznie bardziej przydatne niż umieszczanie wszystkich typów niestandardowych na liście jako ich podstawowe typy pierwotne (tak jakby#define
był używany zamiast tego).źródło
Nie.
Typedef to słowo kluczowe C, które tworzy alias dla typu.
#define to instrukcja preprocesora, która tworzy zdarzenie zamiany tekstu przed kompilacją. Gdy kompilator dotrze do kodu, oryginalne słowo „#defined” już nie istnieje. #define jest używany głównie w przypadku makr i stałych globalnych.
źródło
AFAIK, No.
typedef
pomaga ustawić „alias” do istniejącego typu danych. Np.typedef char chr
;#define
jest dyrektywą preprocesora używaną do definiowania makr lub ogólnych podstawień wzorców. Np.#define MAX 100
, zastępuje wszystkie wystąpieniaMAX
100źródło
Jak wspomniano powyżej, istnieje kluczowa różnica między
#define
i typedef. Właściwy sposób, aby o tym pomyśleć, to zobaczyć typedef jako kompletny typ „hermetyzowany”. Oznacza to, że po zadeklarowaniu nie możesz do niego nic dodawać.Możesz rozszerzyć nazwę typu makra o inne specyfikatory typu, ale nie o nazwę typu zdefiniowaną przez typ:
Ponadto nazwa typedef'd zapewnia typ dla każdego deklaratora w deklaracji.
Po rozwinięciu makra druga linia staje się:
Apple jest wskaźnikiem do int, a banan to int. W porównaniu. taki typ:
deklaruje, że jabłko i banan są takie same. Nazwa na przodzie jest inna, ale oba są wskazówkami do znaku.
źródło
Jak wszyscy powiedzieli powyżej, nie są tacy sami. Większość odpowiedzi wskazuje,
typedef
że są one bardziej korzystne niż#define
. Ale pozwólcie, że dodam plus#define
:kiedy twój kod jest bardzo duży, rozproszony w wielu plikach, lepiej go użyć
#define
; pomaga w czytelności - możesz po prostu wstępnie przetworzyć cały kod, aby zobaczyć rzeczywistą definicję typu zmiennej w miejscu jej deklaracji.źródło