2009-02-01 16 views
32

क्या गुमनाम {} सी शैली भाषाओं (सी, सी ++, C#) में ब्लॉक का उद्देश्य हैसी शैली भाषाओं में अज्ञात {} ब्लॉक का उद्देश्य क्या है?

उदाहरण -



void function() 
{ 

    { 
    int i = 0; 
    i = i + 1; 
    } 

    { 
    int k = 0; 
    k = k + 1; 
    } 

} 

संपादित - उत्कृष्ट जवाब के सभी के लिए धन्यवाद!

+0

पूर्णता के लिए, आप जावा में भी ऐसा कर सकते हैं। –

+0

स्कोप-लॉक कक्षाओं के साथ लॉकिंग: http://stackoverflow.com/questions/500006/what-is-the-purpose-of-anonymous-blocks-in-c-style-languages/4133914#4133914 –

उत्तर

61

यह {} के अंदर ब्लॉक में चर के दायरे को सीमित करता है।

+1

+1 के लिए +1 संक्षिप्त और सटीक उत्तर। –

3

जहां तक ​​मैं समझता हूं, वे बस स्कॉइंग के लिए हैं। वे आपको अभिभावक/भाई के स्कॉप्स में परिवर्तनीय नामों का पुन: उपयोग करने की अनुमति देते हैं, जो समय-समय पर उपयोगी हो सकते हैं।

संपादित करें: वास्तव में इस प्रश्न का उत्तर another Stack Overflow question पर दिया गया है। उम्मीद है की वो मदद करदे।

4

वे अक्सर चर को स्कॉइंग करने के लिए उपयोग किए जाते हैं, ताकि चर ब्रेसिज़ द्वारा परिभाषित मनमाने ढंग से ब्लॉक के लिए स्थानीय हैं। आपके उदाहरण में, वेरिएबल I और k उनके संलग्न ब्रेसिज़ के बाहर पहुंच योग्य नहीं हैं, इसलिए उन्हें किसी भी चुस्त तरीके से संशोधित नहीं किया जा सकता है, और उन चर नामों को आपके कोड में कहीं और दोबारा उपयोग किया जा सकता है। इस तरह के स्थानीय दायरे को बनाने के लिए ब्रेसिज़ का उपयोग करने का एक अन्य लाभ यह है कि कचरा संग्रह वाली भाषाओं में, कचरा कलेक्टर जानता है कि स्कॉप्स चर के बाहर साफ करना सुरक्षित है। यह सी/सी ++ में उपलब्ध नहीं है, लेकिन मेरा मानना ​​है कि यह सी # में होना चाहिए।

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

19

ब्रैकेट्स दायरे के क्षेत्र को निर्दिष्ट करते हैं - ब्रैकेट के भीतर घोषित कुछ भी उनके बाहर अदृश्य है।

इसके अलावा, सी ++ में स्टैक पर आवंटित एक वस्तु (उदा। 'नए' के ​​उपयोग के बिना) को दायरे से बाहर होने पर नष्ट कर दिया जाएगा।

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

6

{ ... } एक नया गुंजाइश

सी ++ में खुल जाता है, तो आप उन्हें इस तरह का उपयोग कर सकते हैं:

void function() { 
    // ... 
    { 
     // lock some mutex. 
     mutex_locker lock(m_mutex); 
     // ... 
    } 
    // ... 
} 

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

एक अन्य उद्देश्य कई समान काम करने के लिए है:

void function() { 
    // set up timer A 
    { 
     int config = get_config(TIMER_A); 
     // ... 
    } 

    // set up timer B 
    { 
     int config = get_config(TIMER_B); 
     // ... 
    } 
} 

यह चीजें अलग तो एक आसानी से विभिन्न निर्माण खंडों पता कर सकते हैं रखेंगे। आप समान नाम वाले वैरिएबल का उपयोग कर सकते हैं, जैसे कोड ऊपर है, क्योंकि वे अपने दायरे से बाहर दिखाई नहीं दे रहे हैं, इस प्रकार वे एक दूसरे के साथ संघर्ष नहीं करते हैं।

4

आप दो चीजें कर रहे हैं।

  1. आप उस ब्लॉक में चर पर एक दायरे प्रतिबंध को मजबूर कर रहे हैं।
  2. आप एक ही चर नामों का उपयोग करने के लिए भाई कोड ब्लॉक सक्षम कर रहे हैं।
+0

2 जीसी कार्यान्वयन के आधार पर 1 –

2

यह गुंजाइश के बारे में है, यह है कि कार्यक्रम के दूसरे भाग के लिए एक कार्यक्रम के एक हिस्से में चर और तरीकों की दृश्यता को संदर्भित करता है, इस उदाहरण पर विचार करें:

int a=25; 
int b=30; 
{ //at this point, a=25, b=30 
    a*=2; //a=50, b=30 
    b /= 2; //a=50,b=15 
    int a = b*b; //a=225,b=15 <--- this new a it's 
        //     declared on the inner scope 
} 
//a = 50, b = 15 
12

वे अक्सर RAII लिए उपयोगी होते हैं उद्देश्यों, जिसका अर्थ है कि जब वस्तु गुंजाइश से बाहर हो जाती है तो दिया गया संसाधन जारी किया जाएगा। उदाहरण के लिए:

void function() 
{ 
    { 
     std::ofstream out("file.txt"); 
     out << "some data\n"; 
    } 
    // You can be sure that "out" is closed here 
} 
3

जैसा कि पिछले पोस्टर का उल्लेख है, यह एक चर के उपयोग को उस दायरे में सीमित करता है जिसमें इसे घोषित किया जाता है।

कचरे में सी # और जावा जैसी एकत्रित भाषाओं में, यह कचरा कलेक्टर को स्कोप के भीतर उपयोग किए जाने वाले किसी भी चर द्वारा उपयोग की जाने वाली मेमोरी को पुनः प्राप्त करने की अनुमति देता है (हालांकि शून्य के चर को सेट करने के समान प्रभाव होता है)।

{ 
    int[] myArray = new int[1000]; 
    ... // Do some work 
} 
// The garbage collector can now reclaim the memory used by myArray 
+0

से असल में निम्नानुसार है, जेआईटी को पहले से ही पता होना चाहिए कि उस चर पर कोई और पढ़ा नहीं गया है, और इसलिए यह संग्रह के लिए पहले से ही योग्य है। –

6
class ExpensiveObject { 
public: 
    ExpensiveObject() { 
     // acquire a resource 
    } 
    ~ExpensiveObject() { 
     // release the resource 
    } 
} 

int main() { 
    // some initial processing 
    { 
     ExpensiveObject obj; 
     // do some expensive stuff with the obj 
    } // don't worry, the variable's scope ended, so the destructor was called, and the resources were released 
    // some final processing 
} 
2

आप ANSI C तक ही सीमित हैं, तो वे चर जहाँ आप उन्हें उपयोग करने के लिए करीब घोषित करने के लिए इस्तेमाल किया जा सकता:

int main() { 
    /* Blah blah blah. */ 
    { 
     int i; 
     for (i = 0; i < 10; ++i) { 
     } 
    } 
} 

एक आधुनिक सी संकलक हालांकि साथ आवश्यक नहीं।

+0

हां, और कभी-कभी यह केवल एक दृश्य चीज है। यह भी ध्यान देने योग्य है कि ब्रेसिज़ के अंदर कुछ भी उन वाक्यविन्यासों के लिए "एक बयान" माना जाता है जो "केवल एक ही कथन स्वीकार करते हैं"। – gbarry

+0

आपका मतलब सी ++ में जरूरी नहीं है, है ना? –

+0

@ वेलेंटीन: हाँ, सी ++ में आपको कहीं भी वैरिएबल घोषित करने की अनुमति है, न केवल ब्लॉक के शीर्ष पर। – Bernard

5

एक नया दायरा बनाकर उनका उपयोग स्विच स्टेटमेंट में स्थानीय चर को परिभाषित करने के लिए किया जा सकता है।

उदा।

glPushMatrix(); 
{ 
    glTranslate(...); 
    glPushMatrix(); 
    { 
     glRotate(...); 
     // draw some stuff 
    } 
    glPopMatrix(); 
    // maybe draw some more stuff 
} 
glPopMatrix(); 
+0

@ फेर्रूसियो: न केवल स्विच स्टेटमेंट में।सी में किसी भी निर्देश से पहले चर को एक दायरे में परिभाषित किया जाना चाहिए। इसलिए यदि आपके पास एक बड़ा फ़ंक्शन है और गणना के लिए अस्थायी चर की आवश्यकता है, तो आप फ़ंक्शन में कहीं भी एक नया दायरा खोल सकते हैं और अपने अस्थायी चर को परिभाषित कर सकते हैं। –

+1

@ वैलेंटिन - यह के एंड आर सी और सी 8 9 के लिए सच था, लेकिन मुझे लगता है कि सी 99 आपको वैरिएबल घोषित करने और प्रारंभ करने की अनुमति देता है, जैसे आपको उनकी आवश्यकता होती है (जैसे सी ++) ताकि आपको इसके लिए स्कॉप्स बनाने की आवश्यकता न हो। हालांकि, आपको अभी भी एक स्विच स्टेटमेंट के भीतर एक दायरा बनाने की आवश्यकता है या संकलक शिकायत कर सकता है कि चर के प्रारंभिकरण को एक या अधिक मामलों में छोड़ दिया गया है। – Ferruccio

7

एक अन्य आम उपयोग ओपन के glPushMatrix() और glPopMatrix() कार्यों मैट्रिक्स ढेर से संबंधित तार्किक ब्लॉक बनाने के लिए के साथ है। (क्या उस घोड़े को अभी तक मार डाला गया है?)

लेकिन अगर आप भाषा परिभाषा को देखो, तुम जैसे पैटर्न देखें:

  • अगर(अभिव्यक्ति)   बयान
  • अगर (अभिव्यक्ति)   बयान   बाकी   बयान
  • स्विच(अभिव्यक्ति)   बयान
  • जबकि(अभिव्यक्ति)   बयान
  •   बयान करना   जबकि(अभिव्यक्ति);

यह भाषा वाक्यविन्यास कि यौगिक बयान कई संभव बयान के में से एक है सरल करता है।


यौगिक बयान:   {बयान-सूची ऑप्ट}

बयान-सूची:

  • राज्य जाहिर
  • बयान-सूची   बयान

बयान:

  • लेबल बयान
  • अभिव्यक्ति बयान
  • +०१२३५१६४१०६१
  • यौगिक बयान
  • चयन बयान
  • यात्रा बयान
  • कूद बयान
  • घोषणा बयान
  • कोशिश ब्लॉक
+0

यह सी/सी ++ के लिए एक अच्छा विचार की तरह लगता है। सी # में, आप 'उपयोग' निर्माण के माध्यम से वही काम करेंगे, जो अंत में मैट्रिक्स को पॉप करना भूलने से बच जाएगा, या अपवाद उठाए जाने पर स्टैक को गड़बड़ कर छोड़ दिया जाएगा। –

3

निश्चित रूप से कार्यक्षेत्र:

switch (i) 
{ 
    case 0 : 
     int j = 0; // error! 
     break; 

बनाम

switch (i) 
{ 
    case 0 : 
    { 
     int j = 0; // ok! 
    } 
    break; 
+0

हाँ, लोग अक्सर भूल जाते हैं कि 'अगर (...) {...} और {...} 'या' के लिए (...) {...} 'अनाम ब्लॉक भी उपयोग कर रहे हैं। असल में इस सवाल को उस आधार पर आधारित किया गया था। – Fizz

0

मैं इसे कोड के ब्लॉक के लिए उपयोग करता हूं जिसके लिए अस्थायी चर की आवश्यकता होती है।

+0

क्या आपका मतलब अस्थायी है? –

+0

हां, क्षमा करें मेरा अंग्रेजी स्तर कम है :( धन्यवाद! –

0

एक उपयोगी उपयोग-कैस ihmo C++ में महत्वपूर्ण अनुभागों को परिभाषित करता है। उदा .:

int MyClass::foo() 
{  
    // stuff uncritical for multithreading 
    ... 
    { 
     someKindOfScopeLock lock(&mutexForThisCriticalResource); 
     // stuff critical for multithreading! 
    } 
    // stuff uncritical for multithreading 
    ...  
} 

गुमनाम गुंजाइश नहीं बुला एक म्युटेक्स की लॉक/अनलॉक या एक सेमाफोर स्पष्ट रूप से की आवश्यकता है का उपयोग कर।

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