#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
STR3 == "s1" ile birleştirmek mümkün mü? Bunu, başka bir Makro işlevine argümanlar aktararak yapabilirsiniz. Ama doğrudan bir yol var mı?
#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
STR3 == "s1" ile birleştirmek mümkün mü? Bunu, başka bir Makro işlevine argümanlar aktararak yapabilirsiniz. Ama doğrudan bir yol var mı?
Yanıtlar:
Her ikisi de dizelerdeyse, şunları yapabilirsiniz:
#define STR3 STR1 STR2
Önişlemci, bitişik dizeleri otomatik olarak birleştirir.
DÜZENLE:
Aşağıda belirtildiği gibi, birleştirmeyi yapan ön işlemci değil derleyicidir.
L"a"
ve "b"
almak için L"ab"
, ama sen yapabilirsiniz bitiştirmek L"a"
ve L"b"
almak için L"ab"
.
Dize değişmezleri için bu tür bir çözüme ihtiyacınız yoktur, çünkü bunlar dil düzeyinde birleştirilir ve yine de çalışmaz çünkü "s" "1" geçerli bir önişlemci simgesi değildir.
[Düzenleme: Maalesef birkaç olumlu oy almış olan aşağıdaki yanlış "Sadece kayıt için" yorumuna yanıt olarak, yukarıdaki ifadeyi tekrarlayacağım ve program parçasının
#define PPCAT_NX(A, B) A ## B
PPCAT_NX("s", "1")
gcc'nin ön işleme aşamasından bu hata mesajını üretir: hata: "" s "" ve "" 1 "" öğelerinin yapıştırılması geçerli bir ön işleme jetonu vermez
]
Ancak, genel simge yapıştırmak için şunu deneyin:
/*
* 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)
Daha sonra, örneğin, her ikisi de PPCAT_NX(s, 1)
ve PPCAT(s, 1)
tanımlayıcı üretmek s1
sürece, s
bir kasa, bir makro olarak tanımlanmaktadır, PPCAT(s, 1)
oluşturur <macro value of s>1
.
Temada devam eden şu makrolar:
/*
* 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)
Sonra,
#define T1 s
#define T2 1
STRINGIZE(PPCAT(T1, T2)) // produces "s1"
Aksine,
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"
C (ve C ++) 'da geçerlidir. Derleyicinin kendisini bir araya getirip tek bir belirteç olarak tehdit edeceği iki simgedir (string değişmezleri).
"s""1" isn't a valid token
- bu doğru; dediğiniz gibi, iki jeton. Ancak bunları ## ile birlikte birleştirmek, onları iki jeton değil, tek bir ön işleme jetonu haline getirir ve böylece derleyici birleştirme yapmaz, bunun yerine sözcü bunları reddeder (dil bir teşhis gerektirir).
STRINGIZE_NX(whatever occurs here)
, her ne olursa olsun, meydana gelen veya burada herhangi bir makro tanımlamadan bağımsız olarak "burada ne olursa olsun" şeklinde genişler.
if A is defined as FRED then STRINGIZE_NX(A) still expands to "FRED"
- bu yanlış ve testiniz gibi değil. Bunu anlamamak veya doğru anlamamak için çok uğraşıyorsun ve ben sana daha fazla cevap vermeyeceğim.
İpucu: Yukarıdaki STRINGIZE
makro harikadır, ancak bir hata yaparsanız ve argümanı bir makro değilse - adda bir yazım hatası yapmışsanız veya #include
başlık dosyasını unuttuysanız - derleyici, sözde makro adını mutlu bir şekilde hatasız dize.
Argümanının STRINGIZE
her zaman normal C değerine sahip bir makro olmasını amaçlıyorsanız, o zaman
#define STRINGIZE(A) ((A),STRINGIZE_NX(A))
bir kez genişletir ve geçerliliğini kontrol eder, atar ve sonra tekrar bir dizeye genişletir.
Dahil etmemiştim yerine neden STRINGIZE(ENOENT)
bittiğini anlamam biraz zaman aldı ."ENOENT"
"2"
errno.h
,
Operatörün doğru kullanımı için önemli gözlem ve +1 . :)
((1),"1") "." ((2),"2")
sadece "1" "yerine" "2" gibi dizilerle sonuçlanır )
STRINGIZE
tanımla "The value of ENOENT is " STRINGIZE(ENOENT)
çalışır, oysa "The value of ENOENT is" STRINGIZE_EXPR(X)
bir hata üretir.