Typedef ve #define c'de aynı mı?


Yanıtlar:


122

Hayır.

#definebir önişlemci belirtecidir: derleyicinin kendisi onu asla görmez.
typedefbir 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 */

3
Typedef'ten sonra, stdfxbu türden geçerli nesneler, bir int alan ve bir değer döndürmeyen işlevlere işaretçilerdir.
pmg

1
#Define, bağımsız değişken olarak işlev göstericisinin casec'inde neden başarısız olur?
Allahjane

2
@Allahjane: genişleme void fx_def(void (*)(int) fx);; doğru beyan şudur void fx_def(void (*fx)(int));.
pmg

5
Fonksiyon işaretçileri sözdizimi vazgeçmeye hazır görünür olmaları gerekir, makro içeren yapılabilir şunlardır: #define FX_TYPE(f) void (*f)(int). Daha sonra işlevinizi şöyle void fx_def(FX_TYPE(fx));
açıklarsınız

229

typedefDeğişkenler gibi kapsam belirleme kurallarına uyar, oysa definederleme biriminin sonuna kadar (veya bir eşleşene kadar undef) geçerli kalır .

Ayrıca, onunla yapılamayan bazı şeyler typedefyapı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

23

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 atüre sahip olacak int *; bbir 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 ave btü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.


13

#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.


#define'ın doğasını bul ve değiştir ile ne demek istiyorsun? , Teşekkürler
Mohamed El Shenawy

1
Bu, derlemeden önce, önişlemcinin tüm makroları bulacağı ve bunları orijinal sözdizimleriyle değiştireceği anlamına gelir
Prince Vijay Pratap

"typedef, türlere takma ad vermek için kullanılabilir" Bu benim için amacımı açıkladı, teşekkürler.
Dave Voyles

8

Önişlemci makroları (" #defines") 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 .


C ++ 'da bir türü nerede yazmanız gerektiğini söyler misiniz? Ben sadece merak ediyorum.
jyz

@jyzuz: Bir üye işlevin bir dizi işlev işaretçisi döndürmesini istiyorsanız bir şey var ya da bunun gibi bir şey - türü hecelemeye çalışırsanız, GCC aslında "typedef kullanmalısınız" der.
Kerrek SB

4

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 #definegibi, derleyici kodu görmeden önce ön işlemci tarafından (kesme ve yapıştırma işlemi gibi) işlenir ve derleyici typedeftarafından yorumlanır.

Ana farklılıklardan biri (en azından veri türlerinin tanımlanması söz konusu olduğunda), typedefdaha 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 typedefs işleme yetenekleri vardır ; bu, tüm özel türlerin temel ilkel türler olarak listelenmesinden çok daha yararlı olabilir ( #definebunun yerine kullanılmış gibi).


2

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.


2
"İşaretçi" teriminin kullanılması burada bazı karışıklıklara yol açabilir.

Kabul. Bu yüzden geri döndüm ve MSDN'de typdef'e bir bağlantı ekledim - gelecekte typedef'in ne olduğunu bulmak için herhangi birinin bu soruyu kullanması ihtimaline karşı. Ama belki de bu kelimeyi değiştirmeliyim ...
Traveling Tech Guy

2

AFAIK, Hayır.

typedefmevcut bir veri türü için bir "takma ad" oluşturmanıza yardımcı olur. Örneğin. typedef char chr;

#definemakroları 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ı MAX100 ile değiştirir


0

Yukarıda bahsedildiği gibi, #definetypedef 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.


-1

Herkesin yukarıda söylediği gibi, aynı değiller. Cevapların çoğu, typedefdaha 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.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.