arahan #define (C/C++)
#define membuat makro, yang merupakan asosiasi pengidentifikasi atau pengidentifikasi berparameter dengan string token. Setelah makro ditentukan, pengkompilasi dapat mengganti string token untuk setiap kemunculan pengidentifikasi dalam file sumber.
Sintaks
#define pengidentifikasi token-stringopt
#define pengidentifikasi ( pengidentifikasimemilih, ... , pengidentifikasi memilih ) keikutsertaan stringtoken
Keterangan
Arahan #define menyebabkan pengkompilasi menggantikan token-string untuk setiap kemunculan pengidentifikasi dalam file sumber. Pengidentifikasi hanya diganti ketika membentuk token. Artinya, pengidentifikasi tidak diganti jika muncul di komentar, dalam string, atau sebagai bagian dari pengidentifikasi yang lebih panjang. Untuk informasi selengkapnya, lihat Token.
Argumen token-string terdiri dari serangkaian token, seperti kata kunci, konstanta, atau pernyataan lengkap. Satu atau beberapa karakter spasi putih harus memisahkan token-string dari pengidentifikasi. Spasi kosong ini tidak dianggap sebagai bagian dari teks yang diganti, atau spasi kosong yang mengikuti token terakhir teks.
#define
Tanpa string token menghapus kemunculan pengidentifikasi dari file sumber. Pengidentifikasi tetap ditentukan dan dapat diuji dengan menggunakan arahan #if defined
dan #ifdef
.
Formulir sintaks kedua mendefinisikan makro seperti fungsi dengan parameter. Formulir ini menerima daftar parameter opsional yang harus muncul dalam tanda kurung. Setelah makro didefinisikan, setiap kemunculan pengidentifikasi berikutnya( pengidentifikasimemilih, ..., pengidentifikasiopt ) diganti dengan versi argumen token-string yang memiliki argumen aktual yang digantikan untuk parameter formal.
Nama parameter formal muncul dalam token-string untuk menandai lokasi tempat nilai aktual diganti. Setiap nama parameter dapat muncul beberapa kali dalam token-string, dan nama dapat muncul dalam urutan apa pun. Jumlah argumen dalam panggilan harus cocok dengan jumlah parameter dalam definisi makro. Penggunaan liberal tanda kurung menjamin bahwa argumen aktual yang kompleks ditafsirkan dengan benar.
Parameter formal dalam daftar dipisahkan oleh koma. Setiap nama dalam daftar harus unik, dan daftar harus diapit dalam tanda kurung. Tidak ada spasi yang dapat memisahkan pengidentifikasi dan tanda kurung pembuka. Gunakan perangkaian garis — letakkan garis miring terbelakang (\
) segera sebelum karakter baris baru — untuk arahan panjang pada beberapa baris sumber. Cakupan nama parameter formal meluas ke baris baru yang mengakhiri token-string.
Ketika makro telah ditentukan dalam formulir sintaks kedua, instans tekstual berikutnya diikuti oleh daftar argumen yang menunjukkan panggilan makro. Argumen aktual yang mengikuti instans pengidentifikasi dalam file sumber dicocokkan dengan parameter formal yang sesuai dalam definisi makro. Setiap parameter formal dalam token-string yang tidak didahului oleh operator stringizing (#
), charizing (#@
), atau token-pasting (##
), atau tidak diikuti oleh ##
operator, digantikan oleh argumen aktual yang sesuai. Makro apa pun dalam argumen aktual diperluas sebelum direktif menggantikan parameter formal. (Operator dijelaskan dalam Operator prapemroscesor.)
Contoh makro berikut dengan argumen mengilustrasikan bentuk kedua sintaks #define :
// Macro to define cursor lines
#define CURSOR(top, bottom) (((top) << 8) | (bottom))
// Macro to get a random integer with a specified range
#define getrandom(min, max) \
((rand()%(int)(((max) + 1)-(min)))+ (min))
Argumen dengan efek samping terkadang menyebabkan makro menghasilkan hasil yang tidak terduga. Parameter formal tertentu mungkin muncul lebih dari satu kali dalam token-string. Jika parameter formal tersebut digantikan oleh ekspresi dengan efek samping, ekspresi, dengan efek sampingnya, dapat dievaluasi lebih dari satu kali. (Lihat contoh di bawah Operator Penempelan Token (##).)
Direktif #undef
menyebabkan definisi pra-prosesor pengidentifikasi dilupakan. Lihat Direktif #undef untuk informasi selengkapnya.
Jika nama makro yang didefinisikan terjadi dalam token-string (bahkan sebagai akibat dari ekspansi makro lain), itu tidak diperluas.
#define kedua untuk makro dengan nama yang sama menghasilkan peringatan kecuali urutan token kedua identik dengan yang pertama.
Khusus Microsoft
Microsoft C/C++ memungkinkan Anda menentukan ulang makro jika definisi baru secara sinonis identik dengan definisi asli. Dengan kata lain, kedua definisi dapat memiliki nama parameter yang berbeda. Perilaku ini berbeda dari ANSI C, yang mengharuskan kedua definisi tersebut identik secara leksikal.
Misalnya, dua makro berikut identik kecuali untuk nama parameter. ANSI C tidak mengizinkan pendefinisian ulang seperti itu, tetapi Microsoft C/C++ mengkompilasinya tanpa kesalahan.
#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( a1 * a2 )
Di sisi lain, dua makro berikut tidak identik dan akan menghasilkan peringatan di Microsoft C/C++.
#define multiply( f1, f2 ) ( f1 * f2 )
#define multiply( a1, a2 ) ( b1 * b2 )
END Khusus Microsoft
Contoh ini mengilustrasikan direktif #define:
#define WIDTH 80
#define LENGTH ( WIDTH + 10 )
Pernyataan pertama mendefinisikan pengidentifikasi WIDTH
sebagai konstanta bilangan bulat 80 dan mendefinisikan dalam hal dan konstanta LENGTH
bilangan WIDTH
bulat 10. Setiap kemunculan LENGTH
digantikan oleh (WIDTH + 10
). Pada gilirannya, setiap kemunculan WIDTH + 10
digantikan oleh ekspresi (80 + 10
). Tanda kurung di sekitar WIDTH + 10
penting karena mereka mengontrol interpretasi dalam pernyataan seperti berikut:
var = LENGTH * 20;
Setelah tahap praproscessing, pernyataan menjadi:
var = ( 80 + 10 ) * 20;
yang mengevaluasi ke 1800. Tanpa tanda kurung, hasilnya adalah:
var = 80 + 10 * 20;
yang mengevaluasi ke 280.
Khusus Microsoft
Menentukan makro dan konstanta dengan opsi pengkompilasi /D memiliki efek yang sama seperti menggunakan direktif praproses #define di awal file Anda. Hingga 30 makro dapat ditentukan dengan menggunakan opsi /D.
END Khusus Microsoft