#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
Apakah mungkin untuk menggabungkan STR3 == "s1"? Anda dapat melakukan ini dengan meneruskan args ke fungsi Makro lainnya. Tetapi apakah ada cara langsung?
#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
Apakah mungkin untuk menggabungkan STR3 == "s1"? Anda dapat melakukan ini dengan meneruskan args ke fungsi Makro lainnya. Tetapi apakah ada cara langsung?
Jawaban:
Jika keduanya adalah string, Anda bisa melakukan:
#define STR3 STR1 STR2
Praprosesor secara otomatis menggabungkan string yang berdekatan.
EDIT:
Seperti disebutkan di bawah ini, bukan preprocessor tetapi kompiler yang melakukan penggabungan.
L"a"dan "b"mendapatkan L"ab", tetapi Anda dapat menggabungkan L"a"dan L"b"mendapatkan L"ab".
Anda tidak memerlukan solusi semacam itu untuk string literal, karena mereka digabungkan pada tingkat bahasa, dan itu tidak akan berfungsi karena "s" "1" bukan token preprocessor yang valid.
[Sunting: Menanggapi komentar "Hanya untuk dicatat" yang salah di bawah ini yang sayangnya menerima beberapa suara positif, saya akan mengulangi pernyataan di atas dan mengamati bahwa fragmen program
#define PPCAT_NX(A, B) A ## B
PPCAT_NX("s", "1")
menghasilkan pesan kesalahan ini dari fase pra-pemrosesan gcc: kesalahan: menempelkan "" s "" dan "" 1 "" tidak memberikan token pra-pemrosesan yang valid
]
Namun, untuk penempelan token umum, coba ini:
/*
* Concatenate preprocessor tokens A and B without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define PPCAT_NX(A, B) A ## B
/*
* Concatenate preprocessor tokens A and B after macro-expanding them.
*/
#define PPCAT(A, B) PPCAT_NX(A, B)
Kemudian, misalnya, keduanya PPCAT_NX(s, 1)dan PPCAT(s, 1)menghasilkan pengenal s1, kecuali jika sdidefinisikan sebagai makro, dalam hal ini PPCAT(s, 1)menghasilkan <macro value of s>1.
Melanjutkan tema adalah makro ini:
/*
* Turn A into a string literal without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define STRINGIZE_NX(A) #A
/*
* Turn A into a string literal after macro-expanding it.
*/
#define STRINGIZE(A) STRINGIZE_NX(A)
Kemudian,
#define T1 s
#define T2 1
STRINGIZE(PPCAT(T1, T2)) // produces "s1"
Sebaliknya,
STRINGIZE(PPCAT_NX(T1, T2)) // produces "T1T2"
STRINGIZE_NX(PPCAT_NX(T1, T2)) // produces "PPCAT_NX(T1, T2)"
#define T1T2 visit the zoo
STRINGIZE(PPCAT_NX(T1, T2)) // produces "visit the zoo"
STRINGIZE_NX(PPCAT(T1, T2)) // produces "PPCAT(T1, T2)"
"s""1"valid dalam C (dan C ++). Mereka adalah dua token (string literal) yang akan disatukan oleh kompiler dan ancaman sebagai satu token.
"s""1" isn't a valid token- itu benar; itu, seperti yang Anda katakan, dua token. Tetapi menyatukannya dengan ## akan membuatnya menjadi token praproses tunggal , bukan dua token, sehingga compiler tidak akan melakukan penggabungan, melainkan lexer akan menolaknya (bahasa ini memerlukan diagnostik).
STRINGIZE_NX(whatever occurs here)berkembang menjadi "apa pun yang terjadi di sini", terlepas dari definisi makro apa pun untuk apa pun, yang terjadi, atau di sini.
if A is defined as FRED then STRINGIZE_NX(A) still expands to "FRED"- itu salah, dan tidak seperti ujian Anda. Anda berusaha keras untuk tidak memahami atau melakukan ini dengan benar, dan saya tidak akan menanggapi Anda lebih jauh.
Petunjuk: STRINGIZEMakro di atas keren, tetapi jika Anda membuat kesalahan dan argumennya bukan makro - Anda memiliki kesalahan ketik pada namanya, atau lupa #includepada file header - maka kompilator akan dengan senang hati memasukkan nama makro yang diklaim ke dalam string tanpa kesalahan.
Jika Anda bermaksud agar argumen ke STRINGIZEselalu makro dengan nilai C normal, maka
#define STRINGIZE(A) ((A),STRINGIZE_NX(A))
akan mengembangkannya sekali dan memeriksa validitasnya, membuangnya, lalu mengembangkannya lagi menjadi string.
Butuh beberapa saat bagi saya untuk mencari tahu mengapa STRINGIZE(ENOENT)berakhir sebagai "ENOENT"alih-alih "2"... Saya tidak memasukkan errno.h.
,operator yang tepat. :)
((1),"1") "." ((2),"2")bukan hanya "1" "." "2")
STRINGIZEdefinisi aslinya , "The value of ENOENT is " STRINGIZE(ENOENT)berfungsi, sedangkan "The value of ENOENT is" STRINGIZE_EXPR(X)menghasilkan kesalahan.