Anda tidak dapat melakukannya jika USER didefinisikan sebagai string yang dikutip.
Tetapi Anda dapat melakukannya jika PENGGUNA hanyalah JACK atau QUEEN atau Joker atau apapun.
Ada dua trik untuk digunakan:
- Token-splicing, di mana Anda menggabungkan pengenal dengan pengenal lain hanya dengan menggabungkan karakternya. Ini memungkinkan Anda membandingkan dengan JACK tanpa harus
#define JACK
melakukan sesuatu
- ekspansi makro variadic, yang memungkinkan Anda menangani makro dengan jumlah variabel argumen. Ini memungkinkan Anda untuk memperluas pengenal tertentu menjadi berbagai jumlah koma, yang akan menjadi perbandingan string Anda.
Jadi mari kita mulai dengan:
#define JACK_QUEEN_OTHER(u) EXPANSION1(ReSeRvEd_, u, 1, 2, 3)
Sekarang, jika saya menulis JACK_QUEEN_OTHER(USER)
, dan USER adalah JACK, preprocessor mengubahnya menjadiEXPANSION1(ReSeRvEd_, JACK, 1, 2, 3)
Langkah kedua adalah penggabungan:
#define EXPANSION1(a, b, c, d, e) EXPANSION2(a##b, c, d, e)
Sekarang JACK_QUEEN_OTHER(USER)
menjadiEXPANSION2(ReSeRvEd_JACK, 1, 2, 3)
Ini memberi kesempatan untuk menambahkan sejumlah koma sesuai dengan apakah string cocok atau tidak:
#define ReSeRvEd_JACK x,x,x
#define ReSeRvEd_QUEEN x,x
Jika USER adalah JACK, JACK_QUEEN_OTHER(USER)
menjadiEXPANSION2(x,x,x, 1, 2, 3)
Jika USER adalah QUEEN, JACK_QUEEN_OTHER(USER)
menjadiEXPANSION2(x,x, 1, 2, 3)
Jika USER lain, JACK_QUEEN_OTHER(USER)
menjadiEXPANSION2(ReSeRvEd_other, 1, 2, 3)
Pada titik ini, sesuatu yang kritis telah terjadi: argumen keempat pada makro EXPANSION2 adalah 1, 2, atau 3, bergantung pada apakah argumen asli yang diberikan adalah jack, queen, atau lainnya. Jadi yang harus kita lakukan adalah memilihnya. Untuk alasan yang bertele-tele, kita membutuhkan dua makro untuk langkah terakhir; mereka akan menjadi EXPANSION2 dan EXPANSION3, meskipun tampaknya tidak diperlukan.
Menggabungkan semuanya, kami memiliki 6 makro ini:
#define JACK_QUEEN_OTHER(u) EXPANSION1(ReSeRvEd_, u, 1, 2, 3)
#define EXPANSION1(a, b, c, d, e) EXPANSION2(a##b, c, d, e)
#define EXPANSION2(a, b, c, d, ...) EXPANSION3(a, b, c, d)
#define EXPANSION3(a, b, c, d, ...) d
#define ReSeRvEd_JACK x,x,x
#define ReSeRvEd_QUEEN x,x
Dan Anda mungkin menggunakannya seperti ini:
int main() {
#if JACK_QUEEN_OTHER(USER) == 1
printf("Hello, Jack!\n");
#endif
#if JACK_QUEEN_OTHER(USER) == 2
printf("Hello, Queen!\n");
#endif
#if JACK_QUEEN_OTHER(USER) == 3
printf("Hello, who are you?\n");
#endif
}
Tautan godbolt wajib: https://godbolt.org/z/8WGa19