Yanıtlar:
Hayır.
#define
bir önişlemci belirtecidir: derleyicinin kendisi onu asla görmez.
typedef
bir derleyici belirtecidir: önişlemci bunu umursamaz.
Aynı etkiyi elde etmek için birini veya diğerini kullanabilirsiniz, ancak ihtiyaçlarınıza uygun olanı kullanmak daha iyidir
#define MY_TYPE int
typedef int My_Type;
İşler "kıllı" olduğunda, doğru aracı kullanmak işi doğru yapar
#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);
void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */
void fx_def(void (*)(int) fx);
; doğru beyan şudur void fx_def(void (*fx)(int));
.
#define FX_TYPE(f) void (*f)(int)
. Daha sonra işlevinizi şöyle void fx_def(FX_TYPE(fx));
typedef
Değişkenler gibi kapsam belirleme kurallarına uyar, oysa define
derleme biriminin sonuna kadar (veya bir eşleşene kadar undef
) geçerli kalır .
Ayrıca, onunla yapılamayan bazı şeyler typedef
yapılabilir define
.
Örneğin:
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
Hayır, onlar aynı değil. Örneğin:
#define INTPTR int*
...
INTPTR a, b;
Önişlemeden sonra bu satır genişler
int* a, b;
Umarım sorunu görürsünüz; sadece a
türe sahip olacak int *
; b
bir düz olarak ilan edilecektir int
(çünkü *
, tür belirleyiciyle değil, tanımlayıcıyla ilişkilidir).
Şununla karşılaştır
typedef int *INTPTR;
...
INTPTR a, b;
Bu durumda, her iki a
ve b
türünde olacaktır int *
.
İşlevlere veya dizilere işaretçiler gibi, bir önişlemci makrosu ile taklit edilemeyen tüm typedef sınıfları vardır:
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
Bunu bir önişlemci makrosuyla yapmayı deneyin.
#define makroları tanımlar.
typedef türleri tanımlar.
Şimdi şunu söyleyelim, işte birkaç fark:
#Define ile derleme zamanında kullanılabilecek sabitleri tanımlayabilirsiniz. Sabitler , kodun nasıl derlendiğini kontrol etmek ve belirli kodu derleme parametrelerine göre özelleştirmek için #ifdef ile birlikte kullanılabilir . #Define işlevini minyatür bul ve değiştir Makro işlevlerini bildirmek için
de kullanabilirsiniz .
typedef , türlere takma adlar vermek için kullanılabilir (ki bunu muhtemelen #define ile de yapabilirsiniz), ancak #define sabitlerinin bul ve değiştir özelliği nedeniyle daha güvenlidir .
Bunun yanı sıra, typedef ile ileri bildirimi kullanabilirsiniz ; bu, kullanılacak olan ancak henüz yazdığınız dosyayla bağlantılı olmayan bir türü belirtmenize olanak tanır.
Önişlemci makroları (" #define
s") sözcüksel bir değiştirme aracıdır ve "ara ve değiştir". Programlama dilinden tamamen habersizler ve ne yapmaya çalıştığınızı anlamıyorlar. Bunları yüceltilmiş bir kopyala / yapıştır teknisyeni olarak düşünebilirsiniz - bazen bu yararlıdır, ancak dikkatli kullanmalısınız.
Yazı tipleri, türler için takma adlar oluşturmanıza izin veren bir C dili özelliğidir. Bu, karmaşık bileşik türleri (yapılar ve işlev işaretçileri gibi) okunabilir ve işlenebilir hale getirmek için son derece kullanışlıdır (C ++ 'da bir tür yazmanız gereken durumlar bile vardır ).
(3) için: Bu mümkün olduğunda her zaman önişlemci makroları yerine dil özelliklerini tercih etmelisiniz! Bu yüzden her zaman türler için typedef'ler ve sabitler için sabit değerler kullanın. Bu şekilde, derleyici aslında sizinle anlamlı bir şekilde etkileşime girebilir. Derleyicinin arkadaşınız olduğunu unutmayın, bu yüzden olabildiğince çok söylemelisiniz. Önişlemci makroları , anlambiliminizi derleyiciden gizleyerek tam tersini yapar .
Genellikle özel veri türlerini uygulamak için kullanılsalar da çok farklıdırlar (ki bu sorunun tümüyle ilgili olduğunu varsayıyorum).
Pmg'den bahsedildiği #define
gibi, derleyici kodu görmeden önce ön işlemci tarafından (kesme ve yapıştırma işlemi gibi) işlenir ve derleyici typedef
tarafından yorumlanır.
Ana farklılıklardan biri (en azından veri türlerinin tanımlanması söz konusu olduğunda), typedef
daha spesifik tür kontrolüne izin vermesidir. Örneğin,
#define defType int
typedef int tdType
defType x;
tdType y;
Burada, derleyici x değişkenini bir int olarak görür, ancak değişken y'yi bir int ile aynı boyutta olan 'tdType' adlı bir veri türü olarak görür. DefType türünde bir parametre alan bir işlev yazdıysanız, arayan normal bir int iletebilir ve derleyici farkı bilemez. İşlev bunun yerine tdType türünde bir parametre alırsa, derleyici işlev çağrıları sırasında uygun türde bir değişkenin kullanıldığından emin olur.
Ayrıca, bazı hata ayıklayıcıların typedef
s işleme yetenekleri vardır ; bu, tüm özel türlerin temel ilkel türler olarak listelenmesinden çok daha yararlı olabilir ( #define
bunun yerine kullanılmış gibi).
Hayır.
Typedef , bir tür için takma ad oluşturan bir C anahtar kelimesidir.
#define, derlemeden önce metin değiştirme olayı oluşturan bir ön işlemci talimatıdır. Derleyici koda ulaştığında, orijinal "#defined" kelimesi artık orada değildir. #define çoğunlukla makrolar ve genel sabitler için kullanılır.
AFAIK, Hayır.
typedef
mevcut bir veri türü için bir "takma ad" oluşturmanıza yardımcı olur. Örneğin. typedef char chr
;
#define
makroları veya genel kalıp ikamelerini tanımlamak için kullanılan bir ön işlemci direktifidir. Örneğin. #define MAX 100
, tüm oluşumlarını MAX
100 ile değiştirir
Yukarıda bahsedildiği gibi, #define
typedef ve typedef arasında önemli bir fark vardır . Bunu düşünmenin doğru yolu, typedef'i tam bir "kapsüllü" tip olarak görmektir. Bu, ilan ettikten sonra ona ekleme yapamayacağınız anlamına gelir.
Bir makro tür adını diğer tür belirticileriyle genişletebilirsiniz, ancak yazılmış bir tür adı olamaz:
#define fruit int
unsigned fruit i; // works fine
typedef int fruit;
unsigned fruit i; // illegal
Ayrıca, typedef'd ad, bildirimdeki her açıklayıcı için tür sağlar.
#define fruit int *
fruit apple, banana;
Makro genişletmeden sonra ikinci satır şu olur:
int *apple, banana;
Apple, bir int için bir işaretçi iken, muz bir int'dir. Karşılaştırıldığında. bunun gibi bir typedef:
typedef char *fruit;
fruit apple, banana;
hem elma hem de muzun aynı olduğunu beyan eder. Ön taraftaki isim farklı, ancak her ikisi de bir karaktere işaret ediyor.
Herkesin yukarıda söylediği gibi, aynı değiller. Cevapların çoğu, typedef
daha avantajlı olduğunu gösteriyor #define
. Ama bir artı noktayı belirtmeme izin verin #define
:
Kodunuz çok büyükse, birçok dosyaya dağılmışsa, kullanmak daha iyidir #define
; okunabilirliğe yardımcı olur - bir değişkenin gerçek tür tanımını, bildiriminin bulunduğu yerde görmek için tüm kodu önceden işleyebilirsiniz.
stdfx
bu türden geçerli nesneler, bir int alan ve bir değer döndürmeyen işlevlere işaretçilerdir.