#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
क्या STR3 == "s1" को संक्षिप्त करना संभव है? आप किसी अन्य मैक्रो फ़ंक्शन में आर्गल्स पास करके ऐसा कर सकते हैं। लेकिन क्या कोई सीधा रास्ता है?
#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
क्या STR3 == "s1" को संक्षिप्त करना संभव है? आप किसी अन्य मैक्रो फ़ंक्शन में आर्गल्स पास करके ऐसा कर सकते हैं। लेकिन क्या कोई सीधा रास्ता है?
जवाबों:
यदि वे दोनों तार हैं तो आप बस कर सकते हैं:
#define STR3 STR1 STR2
प्रीप्रोसेसर स्वतः समीपवर्ती तारों को समेट लेता है।
संपादित करें:
जैसा कि नीचे उल्लेख किया गया है, यह प्रीप्रोसेसर नहीं है लेकिन संकलक है जो संघनन करता है।
L"a"
और "b"
प्राप्त करने के लिए L"ab"
, लेकिन आप कर सकते हैं जोड़ L"a"
और L"b"
प्राप्त करने के लिए L"ab"
।
आपको स्ट्रिंग शाब्दिकों के लिए उस तरह के समाधान की आवश्यकता नहीं है, क्योंकि वे भाषा के स्तर पर संक्षिप्त हैं, और यह वैसे भी काम नहीं करेगा क्योंकि "s" "1" एक वैध प्रीप्रोसेसर टोकन नहीं है।
[संपादित करें: गलत "बस रिकॉर्ड के लिए" टिप्पणी के जवाब में नीचे टिप्पणी की गई है कि दुर्भाग्य से कई upvotes प्राप्त हुए हैं, मैं ऊपर दिए गए कथन को दोहराऊंगा और निरीक्षण करूंगा कि प्रोग्राम टुकड़ा
#define PPCAT_NX(A, B) A ## B
PPCAT_NX("s", "1")
इस त्रुटि संदेश को gcc के प्रीप्रोसेसिंग चरण से उत्पन्न करता है: त्रुटि: "" s "" और "" 1 "" चिपकाना एक मान्य प्रीप्रोसेसिंग टोकन नहीं देता है
]
हालाँकि, सामान्य टोकन चिपकाने के लिए, यह प्रयास करें:
/*
* 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)
फिर, जैसे, दोनों PPCAT_NX(s, 1)
और PPCAT(s, 1)
पहचानकर्ता का उत्पादन s1
, जब तक कि s
कोई मैक्रो, जिसमें मामले के रूप में परिभाषित किया गया है PPCAT(s, 1)
का उत्पादन<macro value of s>1
।
विषय पर जारी ये मैक्रो हैं:
/*
* 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)
फिर,
#define T1 s
#define T2 1
STRINGIZE(PPCAT(T1, T2)) // produces "s1"
इसके विपरीत,
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 (और C ++) में मान्य है। वे दो टोकन (स्ट्रिंग शाब्दिक) हैं जो कंपाइलर स्वयं को सम्मिलित करेगा और एक टोकन के रूप में खतरा होगा।
"s""1" isn't a valid token
- यह सही है; यह है, जैसा कि आप कहते हैं, दो टोकन। लेकिन ## के साथ एक साथ व्यवहार करने से उन्हें एक एकल टोकन होगा, न कि दो टोकन, और इसलिए संकलक एक संघटन नहीं करेगा, बल्कि लेक्सर उन्हें अस्वीकार कर देगा (भाषा को निदान की आवश्यकता है)।
STRINGIZE_NX(whatever occurs here)
"जो कुछ भी यहां होता है", जो भी घटित होता है, या यहाँ के लिए किसी भी स्थूल परिभाषा की परवाह किए बिना विस्तारित होता है।
if A is defined as FRED then STRINGIZE_NX(A) still expands to "FRED"
- यह गलत है, और आपके परीक्षण जैसा कुछ नहीं है। आप इस अधिकार को समझने या न पाने के लिए कठिन प्रयास कर रहे हैं, और मैं आपको आगे जवाब देने नहीं जा रहा हूं।
संकेत: STRINGIZE
ऊपर दिया गया मैक्रो शांत है, लेकिन यदि आप कोई गलती करते हैं और उसका तर्क स्थूल नहीं है - तो आपको नाम में एक टाइपो था, या भूल गया#include
हेडर फ़ाइल में - तब कंपाइलर प्रसन्नतापूर्वक स्थूल मैक्रो नाम में डाल देगा कोई त्रुटि के साथ स्ट्रिंग।
यदि आप चाहते हैं कि तर्क STRINGIZE
हमेशा एक सामान्य सी मान के साथ एक मैक्रो है, तो
#define STRINGIZE(A) ((A),STRINGIZE_NX(A))
एक बार इसका विस्तार करेगा और वैधता के लिए इसकी जांच करेगा, इसे छोड़ देगा, और फिर इसे एक स्ट्रिंग में फिर से विस्तारित करेगा।
मुझे यह पता लगाने में थोड़ा समय लगा कि मैं इसके बजाय क्यों STRINGIZE(ENOENT)
समाप्त हो रहा था ... मैंने शामिल नहीं किया था ।"ENOENT"
"2"
errno.h
,
ऑपरेटर के उचित उपयोग के लिए महत्वपूर्ण अवलोकन, और +1 । :)
((1),"1") "." ((2),"2")
सिर्फ़ "1" "के बजाय" "" 2 ") जैसे अनुक्रम
STRINGIZE
परिभाषा के साथ, "The value of ENOENT is " STRINGIZE(ENOENT)
काम करता है, जबकि "The value of ENOENT is" STRINGIZE_EXPR(X)
एक त्रुटि पैदा करता है।