2015-05-28 6 views
6

में उपयोग करना चाहता हूं, नीचे दिए गए कोड में, मेरे पास एक निश्चित कथन है जो इनपुट स्ट्रिंग 10 वर्णों से कम है। मैंने bool को cont कहा है जिसका उपयोग मैं अपनी शर्तों को पूरा करने के बाद थोड़ी देर के लिए रोकने के लिए कहता हूं।एक चर को अलग करने के लिए घुंघराले ब्रेसिज़ का उपयोग करना जिसे मैं कई बार C++

#include "stdafx.h" 
#include <iostream> 
#include <string> 

int main() 
{ 
    using namespace std; 

    cout << "Enter a string less than 10 characters long: "; 

    string teststring; 

    { 
     bool cont(false); 

     //if input is 10 or more characters, ask for input again until it is less 
     while (!cont) 
     { 
      getline(cin, teststring); 

      if (teststring.length() >= 10) 
      { 
       cout << "Too long, try again: "; 
      } 
      else 
      { 
       cout << "Thank you.\n\n"; 
       cont = true; 
      } 

     } 
    } 

    return 0; 
} 

तुम वहाँ देख सकते हैं, मैं {} रों का एक सेट का उपयोग किया है उन ब्रेसिज़ के भीतर cont चर एक स्थानीय गुंजाइश दे बाहर कोड को अलग करने,। मैंने ऐसा इसलिए किया कि यदि मैं कभी उस वैरिएबल नाम का फिर से उपयोग करना चाहता था, तो मैं इसे फिर से घोषित कर सकता था, और जब मैं इसके साथ कर रहा हूं, तो यह नष्ट हो गया है।

क्या यह एक स्वीकार्य अभ्यास है? या क्या मैंने किया है करने के लिए एक बेहतर तरीका है? मैं स्वीकार करता हूं कि इस विशिष्ट, मूल परिदृश्य में, स्थिति काफी सरल है कि यह शायद ही आवश्यक है, लेकिन मैं भविष्य में अधिक जटिल लूप के लिए ऐसा करना चाहूंगा।

+0

आप क्यों इसे फिर से घोषित करने के लिए आप इसे फिर से उपयोग करने के लिए जा रहे हैं चाहेगा? तुम बस पाश के बाद गलत पर डाल दिया है और इसे पुन: उपयोग करता है, तो आप (गुंजाइश बात के बिना) – moffeltje

+0

चाहते यदि आप पाते हैं अपने आप को यह करने के लिए की आवश्यकता होगी, के लिए, आप एक समारोह में बहुत अधिक कोड हो सकता है। आपको इसे एक अलग समारोह में तोड़ना चाहिए। –

+0

इसी प्रकार के प्रश्न http://stackoverflow.com/questions/21278015/on-using-several-scoped-blocks-in-a-c-function। – AldurDisciple

उत्तर

1

यह एक खिलौना मामला स्पष्ट रूप से है लेकिन यह एक अच्छा अभ्यास है और उस उद्देश्य के लिए 'स्टैंड-अलोन' ब्लॉक हैं। मुझे विश्वास है कि वे सदस्यों में इसे तोड़ने से लंबे कार्यों की संरचना करने का एक बेहतर तरीका हैं (कई मामलों में) का कोई अलग उद्देश्य नहीं है।

इस तरह के एक मामले में आप एक तेजी से, स्पष्ट, सुरक्षित कार्यक्रम प्रदान कर सकते हैं वहाँ एक टिप्पणी (संभवतः एक पंक्ति) है, खासकर यदि प्रत्येक ब्लॉक को शुरू करने।

हालांकि इस मामले में आप सोच सकते हैं:

for (bool cont(false);!cont;) 

कौन सा ही होता है। for(.;.;.) कथन में घोषित वैरिएबल उस कथन के दायरे तक ही सीमित हैं।

for(;;) //<--- Canonical formulation for 'infinite' loop. 
    { 
     getline(cin, teststring); 

     if (teststring.length() >= 10) 
     { 
      cout << "Too long, try again: "; 
     } 
     else 
     { 
      cout << "Thank you.\n\n"; 
      break; //<--- Escapes the loop. 
     } 

    } 

फ़ुटनोट (टिप्पणियों के जवाब में):

आप एक while पाश पर 'वाक्यात्मक चीनी' के रूप में एक for पाश संबंध चाहिए

इस मामले में आप के साथ पूरे चर चकमा कर सकते हैं। यह उनके प्रदर्शन, आदि में कोई अलग नहीं है और केवल सर्वोत्तम पढ़ने वाला व्यक्ति चुनें। for(;cond;) बस मजाकिया लग रहा है।

break पर एक छोटा (छोटा) प्रदर्शन लाभ हो सकता है लेकिन मुझे लगता है कि यह कई मामलों में वास्तव में सरल और अधिक पठनीय है।

तो कोड को और अधिक जटिल थे वहाँ और अधिक 'पाश अंत' कोड तो यह हो जाता है हो सकता है:

for(bool cont(false);!cont;) { 

    //Complex code with multiple 'exit' conditions... 

    if(!cont) { 
     //Go round again code that won't fit nicely in last term of for loop... 
    } 
} 

जबकि break का उपयोग कर सिर्फ एक 'तेज बाहर निकलें' को समझने के लिए आसान बनाता है। वे नहीं (व्यापक रूप से) goto के 'बुरे कर्म' है, क्योंकि वे निष्पादन का एक बहुत ही स्पष्ट रूप से परिभाषित बिंदु 'के पास जाओ' माना जाता है।

+0

वास्तव में यह बहुत अच्छा है। इसलिए हालाँकि कोई शर्त नहीं है, फिर भी 'else' कथन लूप को तोड़ देगा। बुनियादी सामग्री के लिए यह बहुत अच्छा है। क्या थोड़ी देर में लूप स्थिति में बस 'बूल' घोषित करने में कुछ गड़बड़ है? क्या थोड़ी देर के लिए लूप के लिए कोई विशिष्ट लाभ है? मैं एक नौसिखिया हूं, इसलिए मैं इसे पूरी तरह से समझना चाहता हूं। मुझे लगता है कि वहां एक परिदृश्य हो सकता है जहां कई स्थितियों में लूप समाप्त हो जाएगा, और 'बूल' मुझे अधिक सौंदर्यपूर्ण रूप से प्रसन्न करता है। –

+0

मुझे यह एक अच्छा सा पसंद है। लूप के लिए वैसे भी अधिक कार्यक्षमता है, और केवल तोड़ने या एकाधिक समापन की स्थिति होने का विकल्प भी बढ़िया है। धन्यवाद! –

2

सामान्य रूप से? हाँ। यह अच्छा है।

इस विशिष्ट मामले में? नहीं। अनावश्यक आप उस नाम का फिर से उपयोग कर रहे हैं, और इस सरल कोड में आप नहीं जा रहे हैं। तो यह सिर्फ शोर है।

देखें & hellip; यह एक संतुलन है।

मुझे लगता है कि मैं अपने आप को कुछ ऐसे कार्यों में कर रहा हूं जो कई संबंधित SQL कथन निष्पादित करते हैं। प्रत्येक बार जब मैं इसे std::stringstream के साथ ss नामक बना सकता हूं। निश्चित रूप से, मैं प्रत्येक को एक अलग नाम दे सकता हूं, लेकिन यह प्रत्येक कथन निर्माता को अपने दायरे में रखने के लिए त्रुटियों को पूरी तरह से रोकता है।

जब आप लॉक गार्ड की तरह चीजों का उपयोग करते हैं तो यह भी एक बहुत ही आम तकनीक है।

+0

"मैं स्वीकार करता हूं कि इस विशिष्ट, मूल परिदृश्य में, स्थिति काफी सरल है कि यह शायद ही आवश्यक है, लेकिन मैं भविष्य में अधिक जटिल लूप के लिए ऐसा करना चाहूंगा।" –

+0

सहमत हैं कि यह इस परिदृश्य में व्यर्थ है। मुझे लगता है कि मेरा मतलब था कि अगर मेरे पास एकाधिक लूप थे, तो प्रत्येक एक अलग बात कर रहा था, इसलिए मैं सिर्फ एक तटस्थ कार्य नहीं कर सका। लेकिन किसी ने उल्लेख किया कि मैं बस स्थिति के अंदर 'बूल' घोषित कर सकता हूं, जो शायद अधिक समझ में आता है। हालांकि धन्यवाद! –

2

यह एक स्वीकार्य अभ्यास है और आप जो कहते हैं वह ठीक करता है। हालांकि इसका शायद ही कभी उपयोग किया जाता है क्योंकि छोटे कार्यों में, यह स्पष्ट है और इसलिए cont फ़ंक्शन शीर्ष-स्तरीय दायरे में परिवर्तनीय है। यदि आपको लगता है कि आपको किसी बड़े फ़ंक्शन में स्कोप को अलग करने की आवश्यकता है, तो एक स्पष्ट नाम के साथ एक और फ़ंक्शन बनाना आम तौर पर पसंद किया जाता है।

आप उन ब्रेसिज़ के बारे में सोच सकते हैं जैसे नामहीन कार्यों को केवल एक बार बुलाया जाता है। यदि आप इसे स्वयं का उपयोग करके देखते हैं, तो शायद आपको इसे अपना नाम देना चाहिए।

एक अन्य विकल्प पाश के पुनर्लेखन के लिए, cont चर की जरूरत नहीं करने के लिए उदाहरण के लिए है:

string teststring; 
do 
{ 
    cout << "Enter a string less than 10 characters long: "; 
    getline(cin, teststring); 
} while (teststring.length() >= 10); 

cout << "Thank you.\n\n"; 

लेकिन यह हमेशा संभव खासकर यदि आप उत्पादन के लिए रोक स्थिति के आधार पर अलग-अलग संदेश की जरूरत नहीं है।

2

हाँ, यह ठीक है, यदि आप एक अच्छे कारण के लिए फिर से का उपयोग कर एक चर किया जाना है। ताला गार्ड अपने खुद के कोड में सबसे आम उपयोग, और उदाहरण std::stringstream ss की लपट के जवाब में दी गई है। मूल रूप से ऐसा करते हैं कि एक अलग चर नाम चुनने से अधिक अजीब लगता है। जैसे आप lock1, lock2, lock3, लिख रहे हैं, तो ... अपने कोड में।

हालांकि, अधिक स्वीकार्य अभ्यास, लंबे फ़ंक्शन निकायों को कोड गंध के रूप में मानना ​​होगा, और उन्हें अपने कार्यों में दोबारा प्रतिक्रिया देना होगा। जैसे

... 
string teststring; 

{ 
    bool cont(false); 
    //10 lines of code to handle the foo scenario 
} 
{ 
    bool cont(false); 
    //15 lines of code to handle the bar scenario 
} 
... 

यह वह जगह है बेहतर रिफैक्टरिंग द्वारा नियंत्रित की तरह लग रहे करने के लिए:

... 
string teststring; 
foo(teststring); 
bar(teststring); 
... 

void foo(string &teststring){ 
bool cont(false); 
//10 lines of code 
} 

void bar(string &teststring){ 
bool cont(false); 
//15 lines of code 
} 
+1

'std :: lock_guard' बिंदु के लिए उपरोक्त। विचार है कि सभी महत्वपूर्ण वर्गों को एक अलग समारोह में एक समारोह के बीच में अपने 'प्राकृतिक' घर से बाहर निकाला जाना चाहिए पागलपन है। – Persixty

+1

मैंने कहा कि क्या मैं शून्य foo (स्ट्रिंग और टेस्टस्ट्रिंग) का सुझाव दे सकता हूं? अन्यथा आप उन अस्थायी लोगों को पेश करते हैं जो खतरनाक हो सकते हैं (यदि टेस्टस्ट्रिंग बड़ा था)। – Persixty

+1

@DanAllen मैं इसे सरल रखने की कोशिश कर रहा था (पूर्ण जटिलता के लिए प्रभावी आधुनिक सी ++ में आइटम 41 देखें!) ... लेकिन सिर्फ ओपीएस कोड को देखा और वह 'टेस्टस्ट्रिंग' को संशोधित कर रहा है, हां, उन्हें निश्चित रूप से होना चाहिए संदर्भ रहे हैं! धन्यवाद :-) –

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