Jawaban:
Tidak.
#define
adalah token preprocessor: kompilator itu sendiri tidak akan pernah melihatnya.
typedef
adalah token compiler: preprocessor tidak mempedulikannya.
Anda dapat menggunakan salah satu untuk mendapatkan efek yang sama, tetapi lebih baik menggunakan yang tepat untuk kebutuhan Anda
#define MY_TYPE int
typedef int My_Type;
Ketika segala sesuatunya menjadi "berbulu", menggunakan alat yang tepat membuatnya menjadi benar
#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);
; deklarasi yang benar adalah void fx_def(void (*fx)(int));
.
#define FX_TYPE(f) void (*f)(int)
. Anda kemudian akan mendeklarasikan fungsi Anda sebagai:void fx_def(FX_TYPE(fx));
typedef
mematuhi aturan pelingkupan seperti variabel, sedangkan define
tetap valid hingga akhir unit kompilasi (atau hingga cocok undef
).
Juga, beberapa hal dapat dilakukan dengan typedef
yang tidak dapat dilakukan define
.
Sebagai contoh:
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
Tidak, mereka tidak sama. Sebagai contoh:
#define INTPTR int*
...
INTPTR a, b;
Setelah praproses, garis itu meluas ke
int* a, b;
Semoga Anda melihat masalahnya; hanya a
akan memiliki tipe int *
; b
akan dideklarasikan sebagai polos int
(karena *
terkait dengan deklarator, bukan penentu tipe).
Bandingkan itu dengan
typedef int *INTPTR;
...
INTPTR a, b;
Dalam hal ini, keduanya a
dan b
akan memiliki tipe int *
.
Ada seluruh kelas typedef yang tidak bisa ditiru dengan makro preprocessor, seperti pointer ke fungsi atau array:
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
Coba lakukan itu dengan makro praprosesor.
#define mendefinisikan makro.
typedef mendefinisikan tipe.
Sekarang mengatakan itu, berikut adalah beberapa perbedaan:
Dengan #define, Anda dapat menentukan konstanta yang dapat digunakan dalam waktu kompilasi. Konstanta dapat digunakan dengan #ifdef untuk memeriksa bagaimana kode dikompilasi, dan mengkhususkan kode tertentu sesuai dengan parameter kompilasi.
Anda juga dapat menggunakan #define untuk mendeklarasikan fungsi Makro temukan-dan-ganti miniatur .
typedef dapat digunakan untuk memberikan alias pada tipe (yang mungkin bisa Anda lakukan dengan #define juga), tetapi lebih aman karena sifat konstanta #define yang temukan dan ganti .
Selain itu, Anda dapat menggunakan deklarasi maju dengan typedef yang memungkinkan Anda mendeklarasikan tipe yang akan digunakan, tetapi belum ditautkan ke file yang Anda tulis.
Makro preprocessor (" #define
's") adalah alat pengganti leksikal a la "search and replace". Mereka sepenuhnya agnostik dari bahasa pemrograman dan tidak memahami apa yang Anda coba lakukan. Anda dapat menganggap mereka sebagai mekanik salin / tempel yang dimuliakan - terkadang itu berguna, tetapi Anda harus menggunakannya dengan hati-hati.
Typedefs adalah fitur bahasa C yang memungkinkan Anda membuat alias untuk tipe. Ini sangat berguna untuk membuat tipe gabungan yang rumit (seperti struct dan pointer fungsi) dapat dibaca dan diatur (dalam C ++ bahkan ada situasi di mana Anda harus mengetikkan sebuah tipe).
Untuk (3): Anda harus selalu lebih memilih fitur bahasa daripada makro praprosesor jika memungkinkan! Jadi selalu gunakan typedef untuk tipe, dan nilai konstan untuk konstanta. Dengan begitu, kompilator benar-benar dapat berinteraksi dengan Anda secara berarti. Ingatlah bahwa kompilator adalah teman Anda, jadi Anda harus memberitahukannya sebanyak mungkin. Makro preprocessor melakukan kebalikannya dengan menyembunyikan semantik Anda dari compiler.
Mereka sangat berbeda, meskipun mereka sering digunakan untuk mengimplementasikan tipe data khusus (yang saya asumsikan adalah pertanyaan ini).
Seperti yang disebutkan pmg, #define
ditangani oleh pra-prosesor (seperti operasi potong-dan-tempel) sebelum kompilator melihat kode, dan typedef
diinterpretasikan oleh kompilator.
Salah satu perbedaan utama (setidaknya dalam hal mendefinisikan tipe data) adalah typedef
memungkinkan pemeriksaan tipe yang lebih spesifik. Sebagai contoh,
#define defType int
typedef int tdType
defType x;
tdType y;
Di sini, compiler melihat variabel x sebagai int, tetapi variabel y sebagai tipe data yang disebut 'tdType' yang ukurannya sama dengan int. Jika Anda menulis fungsi yang mengambil parameter tipe defType, pemanggil bisa meneruskan int normal dan kompilator tidak akan tahu bedanya. Jika fungsi tersebut mengambil parameter tipe tdType, compiler akan memastikan bahwa variabel dengan tipe yang tepat digunakan selama panggilan fungsi.
Selain itu, beberapa debugger memiliki kemampuan untuk menangani typedef
s, yang bisa jauh lebih berguna daripada mencantumkan semua tipe kustom sebagai tipe primitif yang mendasarinya (seperti yang akan terjadi jika #define
digunakan sebagai gantinya).
Tidak.
Typedef adalah kata kunci C yang membuat alias untuk suatu tipe.
#define adalah instruksi pra-prosesor, yang membuat peristiwa penggantian teks sebelum kompilasi. Ketika kompilator mendapatkan kode tersebut, kata "#defined" asli tidak ada lagi. #define sebagian besar digunakan untuk makro dan konstanta global.
AFAIK, Tidak.
typedef
membantu Anda menyiapkan "alias" untuk tipe data yang ada. Misalnya. typedef char chr
;
#define
adalah arahan preprocessor yang digunakan untuk mendefinisikan makro atau substitusi pola umum. Misalnya. #define MAX 100
, gantikan semua kemunculan MAX
dengan 100
Seperti disebutkan di atas, ada perbedaan utama antara #define
dan typedef. Cara yang tepat untuk memikirkannya adalah dengan melihat typedef sebagai tipe "dikemas" yang lengkap. Artinya Anda tidak dapat menambahkannya setelah Anda mendeklarasikannya.
Anda bisa memperluas nama jenis makro dengan penentu jenis lain, tapi bukan nama jenis yang diketik:
#define fruit int
unsigned fruit i; // works fine
typedef int fruit;
unsigned fruit i; // illegal
Selain itu, nama typedef menyediakan tipe untuk setiap deklarasi dalam deklarasi.
#define fruit int *
fruit apple, banana;
Setelah ekspansi makro, baris kedua menjadi:
int *apple, banana;
Apel adalah penunjuk ke int, sedangkan banana adalah int. Dibandingkan. seorang typedef seperti ini:
typedef char *fruit;
fruit apple, banana;
menyatakan apel dan pisang sama. Nama di depan berbeda, tetapi keduanya mengarah ke karakter.
Seperti yang dikatakan semua orang di atas, mereka tidak sama. Sebagian besar jawaban menunjukkan typedef
lebih menguntungkan daripada #define
. Tapi izinkan saya memberi nilai tambah #define
:
ketika kode Anda sangat besar, tersebar di banyak file, lebih baik digunakan #define
; itu membantu dalam keterbacaan - Anda cukup memproses semua kode untuk melihat definisi tipe sebenarnya dari variabel di tempat deklarasinya sendiri.
stdfx
, objek yang valid dari tipe tersebut adalah pointer ke fungsi yang menerima int dan tidak mengembalikan nilai.