2010-04-06 9 views
12

मैं रिकर्सन के साथ खेल रहा था और यह आसान काम किया। मैं मान रहा था कि यह 9-0 से बाहर निकल जाएगा, लेकिन, यह 0-9 प्रिंट करता है। मैं नहीं देख सकता कि यह कैसे होता है।यह रिकर्सिव फ़ंक्शन मुझे पहेली करता है, क्या चल रहा है?

int main() 
{ 
     rec(10); 
     return 0; 
} 

int rec(int n){ 
     if(n > 0) 
       printf("%d\n", rec(n -1)); 
     return n; 
} 
+7

यदि नीचे दिए गए स्पष्टीकरण 'क्लिक' नहीं करते हैं, तो हो सकता है कि आप क्या चल रहे हैं यह देखने के लिए डीबगर में निष्पादन के बावजूद कदम उठाने के लिए अच्छा प्रदर्शन हो सकता है। –

+0

वैसे, जबकि एक अच्छा प्रोग्रामर इस फ़ंक्शन को पढ़ने में सक्षम होने की उम्मीद है (एक साक्षात्कार के दौरान शायद), उन्हें कभी इस तरह कोड नहीं लिखना चाहिए। अच्छा कोड आपको नहीं सोचना चाहिए। –

उत्तर

9

माइकल बर टिप्पणी में कहते हैं, अगर आप को देखने के लिए क्या हो रहा है चाहता हूँ, डिबगिंग प्रतीकों के साथ संकलन सक्षम है, तो इस तरह:

gcc -o test -g test.c 

फिर जीडीबी के साथ चलाएं।

gdb test 

फिर, बातें जा रहा है, प्रकार

start 

कौन सा मुख्य समारोह में पहली कॉल पर टूट जाता है शुरू करने के लिए। टाइप करें

step 

कोड में अगली पंक्ति में जाने के लिए, और तब से, अंतिम आदेश दोहराने के लिए केवल एंटर दबाएं। यदि आप खुश हैं, तो चरणबद्ध होने से रोकने के लिए continue टाइप करें। आप प्रत्येक चरण में मूल्यों और मूल्यांकन लाइनों को देखेंगे जो उपरोक्त उत्तरों की पुष्टि करेंगे।

आशा है कि कुछ उपयोगी जानकारी प्रदान करेगी।

+1

एक और उपयोगी जीडीबी कमांड 'सूची' है, जो आपको आपकी स्रोत फ़ाइल से कुछ पंक्तियां दिखाता है। –

+0

@ थॉमस आपको लगता है कि कुछ भी संपादित करने में स्वतंत्र महसूस होता है! –

+0

धन्यवाद, यह बढ़िया है। मुझे gdb के साथ बहुत अधिक अनुभव नहीं है, इसलिए यह सही है। मै उसे करने की एक कोशिश तो करूंगा। – Fred

19

printf लाइन पर rec समारोह printf खुद से पहले मूल्यांकन किया जाता है। इस प्रकार गहराrec फ़ंक्शन का उदाहरण पहले मुद्रित किया गया है।

+0

मुझे लगता है कि मैं इस तथ्य से उलझन में था कि printf भी आरईसी समारोह का हिस्सा है। स्पष्टीकरण के लिए धन्यवाद, मैंने अभी इसके साथ शुरुआत की। – Fred

+0

कोई समस्या नहीं, मदद करने में खुशी हुई। बस याद रखें कि कार्यों का मूल्यांकन हमेशा अंदरूनी हो जाता है: पैरामीटर का मूल्यांकन फ़ंक्शन से पहले किया जाता है। – tloflin

11

इस तरह के बारे में सोचें।

rec(10) 
rec(9) 
rec(8) 
rec(7) 
rec(6) 
rec(5) 
rec(4) 
rec(3) 
rec(2) 
rec(1) 
rec(0) 

प्रारंभ Unwinding

printf("%d\n", 0); 
printf("%d\n", 1); 
printf("%d\n", 2); 
printf("%d\n", 3); 
printf("%d\n", 4); 
printf("%d\n", 5); 
printf("%d\n", 6); 
printf("%d\n", 7); 
printf("%d\n", 8); 
printf("%d\n", 9); 
+0

धन्यवाद, यह एक अच्छा स्पष्टीकरण है। जैसा कि सुझाव दिया गया था, मैं डीबगर में भी एक नज़र डालेगा। – Fred

10

के इस तरह अपने कोड को फिर से लिखने करते हैं:

int rec(int n){ 
     if(n > 0) 
     { 
       int retval = rec(n -1); 
       printf("%d\n", retval); 
     } 
     return n; 
} 

यह यह स्पष्ट क्यों 0 9 से पहले पहली मुद्रित कर देता है?

+0

मैं आमतौर पर ऐसे कार्यों को घोंसला करता हूं यदि मैं उन्हें मुद्रित करना चाहता हूं, तो यह तथ्य है कि printf भी रिक फ़ंक्शन का हिस्सा है जिसने मुझे उलझन में पाया। धन्यवाद – Fred

3

क्योंकि आप 9 परिवेश 9 > 8 > 7 > 6 > 5 > 4> 3 > 2 > 1 > 0 बना रहे हैं, अब इन परिवेशों का इलाज a(b(c(d(e(f(g())))))) होगा, जो सबसे गहरे से पहले तक जा रहे हैं।

याद रखें कि जब आप यह printf("%d",n(m)); करते हैं तो आप वास्तव में कुछ भी प्रिंट नहीं कर रहे हैं, आप कह रहे हैं "एन (एम) के परिणाम प्रिंट करें" फिर जब यह n (m) को हल करने का प्रयास करता है तो आप एक और प्रिंट कॉल कर रहे हैं और एक बार फिर कहा "एन (एम -1) हल करें"।

अब, जब आप n तक पहुँचने (0) यह 0 वापस आ जाएगी printf की आखिरी कॉल द्वारा मुद्रित करने के लिए है, इसलिए यह प्रिंट 0 तो 1 .. 9.

+0

धन्यवाद, यह बहुत उपयोगी है! मैंने वास्तव में पहले भी बहुत कुछ नहीं दिया है, और इसके साथ कुछ प्रयोग करने शुरू करने का फैसला किया है। यह समझ आता है। – Fred

0
int main() 
{ 
     rec(10); 
     return 0; 
} 

int rec(int n){ 
     if(n > 0) 
       printf("%d\n", rec(n -1)); 
     return n; 
} 

सामान्य तौर पर, कुछ टुकड़ा पर विचार कोड का हम कहते हैं कि पुनरावर्तक और पुनरावर्ती समाधानों के बीच सीधा संबंध है कि किसी भी समाधान को इसके विपरीत और विपरीत बना दिया जा सकता है। हालांकि, कुछ मामलों में इसे एक एल्गोरिदम को दोबारा व्यक्त करना आसान होता है (उदाहरण के लिए हनोई का टॉवर।) बराबर के ऊपर कोड के मामले में लूप निर्माण के लिए होगा।

void _for(int i, int n) 
{ 
    if(i >= n) return; // TERMINAL<br /> 
    // some expression (ie. printf("%d\n",i);)<br /> 
    _for(i+1,n) // RECURSION<br /> 
} 

ध्यान दें, यह समारोह संकेत का उपयोग कर बढ़ाया जा सकता है:

यह इस प्रकार एक समारोह के रूप में लागू किया जा सकता है।

+0

मार्कडाउन संपादक एफएक्यू को देखना चाहते हैं। http://stackoverflow.com/editing-help – ChaosPandion

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