2013-10-05 28 views
11

मेरे पास एक कार्यक्रम है।सी # में वास्तव में क्या करता है?

#include <stdio.h> 

#define f(a,b) a##b 
#define g(a) #a 
#define h(a) g(a) 

int main() 
{ 
     printf("%s\n",h(f(1,2))); 
     printf("%s\n",g(f(1,2))); 
     return 0; 
} 

इस कार्यक्रम के ठीक से काम और के रूप में उत्पादन दे रही है:

12 
f(1, 2) 

कैसे संकलक इस उत्पादन दे रही है मुझे समझ नहीं आता।

a##b और #a में # का कार्य क्या है?

+0

http://stackoverflow.com/questions/16989730/c-stringify-how-does-it-work –

+0

@YuHao, मैं सच में माफी चाहता हूँ । मैंने इस सवाल की खोज की। मुझे कोई संबंधित नहीं मिला। क्योंकि मुझे नहीं पता # स्ट्रिंग को बुलाया जाता है। – SGG

+0

@ एसजीजी अरे, यह ठीक है क्योंकि इस प्रश्न की खोज करना मुश्किल है क्योंकि कोई विशेष कीवर्ड नहीं है। मुझे पहले इस कार्यक्रम को देखना याद है और डुप्लिकेट खोजने के लिए कई मिनट बिताए हैं :) यहां तक ​​कि '#' और '##' के मूल उपयोग को भी जानना, यह सवाल अभी भी मुश्किल है। –

उत्तर

4

मुझे इसे तोड़ने के नीचे आप के लिए करते हैं:

#define f(a,b) a##b //2 this macro is evaluated first with a = 1 and b = 2 it concatenates them and returns 12 
#define g(a) #a //4 g turns 12 into "12" (string) 
#define h(a) g(a) //3 back to h which now has a = 12 and call g() 

int main() 
{ 
     printf("%s\n",h(f(1,2)));//1 printf calls the macro h() and gives it the macro f() as an argument 
     printf("%s\n",g(f(1,2)));// g here turns f(1,2) into "f(1,2)" (string) 
     return 0; 
} 
+0

आम तौर पर सही है, लेकिन बाद में (1) पहले 'एच()' परिभाषा (2) के रूप में आता है, जो बदले में "सक्रिय" 'f()' होता है, जो (3) और फिर 'g()' (4)। – glglgl

12

## संयोजित दो टोकन एक साथ।

महत्वपूर्ण बात यह है कि यह केवल पूर्वप्रक्रमक में इस्तेमाल किया जा सकता है।

# ऑपरेटर टोकन stringify किया जाता है।

उदाहरण के लिए: -

#(a ## b) जो #ab जो हो जाता है "ab"

तो ज (च (1,2)) हो जाता है "च (1,2)"

यह भी ध्यान रखें हो जाता है कि # और ## दो अलग ऑपरेटर हैं।

पूर्वप्रक्रमक ऑपरेटर ## मैक्रो विस्तार के दौरान वास्तविक तर्क को श्रेणीबद्ध करने के लिए एक तरीका प्रदान करता है। प्रतिस्थापन पाठ में एक पैरामीटर एक ## के निकट है, तो पैरामीटर वास्तविक तर्क, ## और सफेद स्थान के आसपास के द्वारा बदल दिया जाता निकाल दिए जाते हैं, और परिणाम फिर से स्कैन किया जाता है।

भी अधिक जानकारी के लिए इस Concatenation जाँच।

here से: -

Stringification

कभी कभी आप एक स्ट्रिंग निरंतर में एक मैक्रो तर्क कन्वर्ट करने के लिए कर सकते हैं। पैरामीटर को स्ट्रिंग स्थिरांक के अंदर प्रतिस्थापित नहीं किया गया है, लेकिन आप '#' प्रीप्रोसेसिंग ऑपरेटर का उपयोग का उपयोग कर सकते हैं। जब एक मैक्रो पैरामीटर का उपयोग अग्रणी '#' के साथ किया जाता है, तो प्रीप्रोसेसर इसे वास्तविक तर्क के शाब्दिक पाठ के साथ बदल देता है, जो एक स्ट्रिंग स्थिर में परिवर्तित होता है। सामान्य पैरामीटर प्रतिस्थापन के विपरीत, तर्क मैक्रो-विस्तारित पहले नहीं है। इसे स्ट्रिंगफिकेशन कहा जाता है।

आसपास के पाठ के साथ एक बहस गठबंधन करने के लिए और यह सब एक साथ stringify कोई तरीका नहीं है। इसके बजाय, आप आसन्न स्ट्रिंग स्थिरांक और स्ट्रिंग किए गए तर्कों की एक श्रृंखला लिख ​​सकते हैं। प्रीप्रोसेसर स्ट्रिंग स्थिरांक के साथ स्ट्रिंग किए गए तर्कों को प्रतिस्थापित करेगा।सी कंपाइलर तब सभी आसन्न स्ट्रिंग स्थिरांक को एक लंबी स्ट्रिंग में जोड़ देगा।

+0

+1 आप उल्लेख करना चाहेंगे कि '#' और '##' दो अलग-अलग ऑपरेटरों हैं। – dasblinkenlight

+0

परिणाम में अंतर क्यों है यदि हमारे पास लगभग समान कॉल हैं? – this

+1

@ स्वयं। वे "लगभग समान" कैसे हैं? 2 * 12 और 2 + 12 भी "लगभग समान" हैं और पूरी तरह से अलग परिणाम उत्पन्न करते हैं। – glglgl

4

## "टोकन-पेस्ट" ऑपरेटर, या "विलय" ऑपरेटर जो एक वास्तविक तर्क बनाने के लिए दो टोकन गठबंधन करने के लिए इस्तेमाल किया जा सकता कहा जाता है।

# स्ट्रिंगिंग ऑपरेटर कहलाता है जो "पैरामीटर परिभाषा को विस्तार किए बिना स्ट्रिंग अक्षर में मैक्रो पैरामीटर को परिवर्तित करता है"।

इन्हें आमतौर पर प्रीप्रोसेसर ऑपरेटर कहा जाता है। इन तरह कुछ और प्रीप्रोसेसर ऑपरेटर मौजूद हैं। अधिक स्पष्टीकरण के लिए सी (http://msdn.microsoft.com/en-us/library/wy090hkc.aspx) में प्रीप्रोसेसर ऑपरेटर देखें।


इसके अलावा http://msdn.microsoft.com/en-us/library/3sxhs2ty.aspx चेकआउट और "यह भी देख 'सी प्रीप्रोसेसर बारे में अधिक जानकारी के लिए उस पृष्ठ की धारा।

संबंधित मुद्दे