2012-04-25 10 views
6

मैं कुछ होमवर्क पर काम कर रहा हूं और जानना चाहता हूं कि लूप्स के दौरान बहुत सी घोंसला जैसी चीज है या नहीं। क्या loops के दौरान कई घोंसले करने के लिए downsides है? यदि ऐसा है तो मेरे पास नीचे दिए गए कोड स्निपेट को दोबारा कैसे बदला जाएगा?लूप के दौरान कई घोंसले के साथ समस्याएं हैं?

नीचे एक फ़ाइल को एक पंक्ति को पढ़ने के लिए कोड है, कुछ परिभाषित डिलीमीटर द्वारा सीमित फ़ील्ड को पार्स करें, और कंसोल पर प्रिंट करने से पहले अग्रणी सफेद स्थान हटा दें।

// Read the file one line at a time 
while (fgets(lineStr, MAXLINELENGTH, fp) != NULL) 
{ 
    charPtr = strtok(lineStr, DELIMITERS); 

    // Loop until line is parsed 
    while (charPtr != NULL) 
    { 
     // Skip past leading whitespace 
     while (isspace(*charPtr)) 
      charPtr++; 

     puts(charPtr); 
     charPtr = strtok(NULL, DELIMITERS); 
    } 
} 
+6

नहीं, नेस्टेड लूप में कोई समस्या नहीं है। – pmg

+1

यद्यपि, आप उनमें से कुछ को उन तरीकों से जोड़ना चाहते हैं जो वे कर रहे हैं यह दर्शाते हैं कि आखिरी व्यक्ति 'स्किपस्पेस()' या कुछ ऐसे हो जाता है। –

+0

यदि इनपुट में ऋणात्मक वर्ण (* 127 * से बड़े मानों के साथ) हो सकते हैं, तो आप अपरिभाषित व्यवहार से बचने के लिए तर्क को 'जारीस्थान' पर डालना चाहते हैं: 'जारीस्थान ((हस्ताक्षरित चार) * charPtr) ' – pmg

उत्तर

6

यह वास्तव में एक बल्कि व्यक्तिपरक विषय है। मेरे विचार में, लूप के दौरान तीन नेस्टेड के साथ मौलिक रूप से गलत कुछ भी नहीं है, लेकिन आप स्वीकार्यता की सीमा तक पहुंच रहे हैं। क्या आप घोंसले के एक या दो स्तरों को जोड़ना चाहते थे, तो आप मेरे विचार में, पाठक को समझने के लिए उचित होने की सीमा को पार करेंगे। मानव मस्तिष्क केवल समय पर किसी भी बिंदु पर इतनी जटिलता को संभाल सकता है।

कुछ लोग तर्क देंगे कि मेरी राय का मुकाबला होगा कि एक समारोह में घोंसले के एक से अधिक स्तर नहीं होने चाहिए, और कार्यों में कोड की लगभग 10 पंक्तियों से अधिक नहीं होना चाहिए। काउंटर तर्क यह है कि इस तरह की नीति के परिणामस्वरूप अधिक खंडित, विवादित कोड हो सकता है। अंगूठे का मेरा नियम यह है कि यदि आप कोड के एक हिस्से के लिए एक अच्छा फ़ंक्शन नाम नहीं सोच सकते हैं, तो शायद कोड का हिस्सा वास्तव में एक समारोह के रूप में अकेले खड़े होने का मतलब नहीं है।

इस तरीके को तोड़ने के तरीकों को देखते हुए, कुछ स्पष्ट विकल्प हैं।

  1. बाहरी समारोह while के शरीर को एक अलग समारोह में निकालें। वह निकाला गया कार्य एक पंक्ति को संसाधित करेगा। इसे पढ़ने और पढ़ने के लिए स्पष्ट करना आसान होगा।
  2. while लूप निकालें जो व्हाइटस्पेस को एक अलग फ़ंक्शन में छोड़ देता है। फिर से नाम करना आसान होगा और आपके कोड को पढ़ने में आसान बना देगा। आप व्हाइटस्पेस टिप्पणी को हटा देंगे क्योंकि निकाले गए फ़ंक्शन का नाम इसे अनावश्यक प्रदान करेगा। शायद यह करने लायक है।

आप इन विचारों को लागू किया है, तो आपके कोड एक छोटे से इस प्रकार दिखाई देंगे:

char* skipWhitespace(char* str) 
{ 
    while (isspace(*str)) 
     str++; 
    return str; 
} 

void parseLine(char *lineStr) 
{ 
    charPtr = strtok(lineStr, DELIMITERS); 
    while (charPtr != NULL) 
    { 
     charPtr = skipWhitespace(charPtr); 
     puts(charPtr); 
     charPtr = strtok(NULL, DELIMITERS); 
    } 
} 
...... 
while (fgets(lineStr, MAXLINELENGTH, fp) != NULL) 
    parseLine(lineStr); 

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

आखिरकार, वास्तव में कठिन और तेज़ नियम नहीं हैं, और यह निर्णय और व्यक्तिगत वरीयता के लिए आता है। मेरे विचार में, प्रश्न में कोड बहुत स्पष्ट और पठनीय है, लेकिन मेरे विचार में, रिफैक्टर संस्करण सिर्फ थोड़ा स्पष्ट है।

अस्वीकरण: मैं कोड की शुद्धता या अन्यथा के बारे में कोई टिप्पणी नहीं करता हूं। मैंने बस उस पहलू को नजरअंदाज कर दिया।

+1

मुझे अंगूठे का आपका कोई नाम नहीं, कोई फ़ंक्शन नहीं है। जाहिर है, केवल एक दिशानिर्देश है, लेकिन यह घर को एक अच्छा बिंदु लाता है - यदि आप वर्णन नहीं कर सकते कि फ़ंक्शन क्या करेगा, तो शायद आपको इसे कार्य करने की आवश्यकता नहीं है! – corsiKa

+0

रिफैक्टर कोड के लिए धन्यवाद। प्रोफेसर से पूछना होगा। अगर वह कोड को पसंद करता है या व्यक्तिगत नेस्टेड लूप को अपने कार्यों में दोबारा पसंद किया जाएगा। मुझे टिप्पणियां नहीं होने का विचार पसंद है क्योंकि फ़ंक्शन का नाम विचार व्यक्त करने के लिए पर्याप्त स्पष्ट है। – Peter

+0

आप कौन सा पसंद करते हैं? आपको कम से कम एक राय होनी चाहिए और जब आप अपने प्रोफेसर में जाते हैं तो एक तरफ बहस करने के लिए तैयार रहें। –

3

एकमात्र असली नकारात्मकता पठनीयता है, जिसके लिए वास्तव में कोई कठोर और तेज़ नियम नहीं हैं ... हालांकि 3 से अधिक घोंसले आमतौर पर किसी और के साथ काम कर रहे हैं जिससे आप काम कर रहे हैं। जैसा कि एक और पोस्टर ने कहा था, कभी-कभी लूप को किसी अन्य फ़ंक्शन पर ले जाकर घोंसला तोड़ना बेहतर होता है, लेकिन आपके पास जो कुछ है वह मेरे लिए पूरी तरह से पठनीय है - और यह केवल वास्तविक मीट्रिक है; शुद्ध व्यक्तिपरक राय :)

0

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

ध्यान दें कि यह आपके उदाहरण के लिए विशेष रूप से महत्वपूर्ण नहीं है, हालांकि, यदि आप कई मेमोरी एक्सेस कर रहे हैं, तो यह एक महत्वपूर्ण प्रदर्शन वृद्धि या कमी हो सकती है। यदि आप पंक्ति-प्रमुख वास्तुकला पर कॉलम-वार फैशन में बहु-आयामी सरणी को पार कर रहे हैं, तो कई कैश मिस होने की संभावना है (ध्यान दें कि रीयल-टाइम के मामले में कैश मिस बहुत महंगा है)।

तो घोंसले की लूप जरूरी नहीं है, लेकिन यह निश्चित रूप से कुछ मनमानी संख्या एन loops के बाद प्रदर्शन पर ध्यान देने योग्य प्रभाव हो सकती है।

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