2010-08-09 16 views
16

संभव डुप्लिकेट:2 लूप चर के साथ सी ++ में फॉर-लूप लिखना इतना कठिन क्यों है?

int myIndex; 
for (myIndex=0;myIndex<10;++myIndex) ... 

एक C++ डेवलपर इस लिखते थे पाश के बाहर लीक से पाश चर को रोकने के लिए:
In C++ why can’t I write a for() loop like this: for(int i = 1, double i2 = 0; …

एसी डेवलपर इस बारे में होगा:

for (int myIndex=0;myIndex<10;++myIndex) ... 

हालांकि, यदि आपके पास 2 लूप चर हैं, तो आप इसे और नहीं कर सकते हैं। निम्नलिखित संकलित करता है नहीं:

for (int myIndex=0,MyElement *ptr=Pool->First;ptr;++myIndex,ptr=ptr->next) ... 

अल्पविराम ऑपरेटर दो चर इस तरह से परिभाषित किया जा करने की अनुमति नहीं है, तो हम इसे इस तरह लिखने के लिए है:

int myIndex; 
MyElement *ptr; 
for (myIndex=0,ptr=Pool->First;ptr;++myIndex,ptr=ptr->next) ... 

कौन सा होने का लाभ धरा वास्तविक पाश-स्थानीय चर।

एक समाधान इस तरह, ब्रेसिज़ के बीच पूरे निर्माण डाल करने के लिए हो सकता है:

{ 
int myIndex; 
MyElement *ptr; 
for (myIndex=0,ptr=Pool->First;ptr;++myIndex,ptr=ptr->next) ... 
} 

लेकिन यह शायद ही और अधिक सुरुचिपूर्ण है।

क्या सी ++ (या सी ++ 0x) में ऐसा करने का कोई बेहतर तरीका नहीं है?

+1

क्यों एक सी प्रोग्रामर जरूरी पाश ऊपर चर जाते थे? – GManNickG

+7

@GMan इसे कथन के अंदर घोषित करना केवल सी 99 के बाद मान्य है, आईआईआरसी – Wim

+7

@Wim: जो 11 साल पहले था। :) – GManNickG

उत्तर

23

आपको सिर्फ यह समझना है कि पहला कथन एक घोषणा है (और वह अल्पविराम अल्पविराम ऑपरेटर नहीं है)।

for (int i, double d; ...) 

से यह है:

int i, double d; 

क्योंकि for (init cond; expr) statement करने के लिए विस्तारित हो जाता है: यह किसी भी कठिन करने के लिए नहीं है बनाने के लिए किया जाता है

{ 
    init 
    while (cond) 
    { 
     statement 
     expr; 
    } 
} 

एक चाल है कि init बयान एक struct परिभाषा और उदाहरण, जैसे:

for (struct { int myIndex; MyElement* ptr;} data = {0, Pool->First}; 
    data.ptr; 
    ++data.myIndex, data.ptr = data.ptr->next) 
    { 
     // blah... 
    } 
,210

कौन सा रूप में एक ही हो जाता है:

{ 
    struct 
    { 
     int myIndex; 
     MyElement* ptr; 
    } data = {0, Pool->First}; 

    while (data.ptr) 
    { 
     { 
      // blah... 
     } 
     ++data.myIndex, data.ptr = data.ptr->next; 
    } 
} 

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

मुझे नहीं लगता कि बॉयलरप्लेट कोड के बिना यहां सुधार करने के लिए बहुत कुछ है।

+2

ओह यह एक बदसूरत समाधान है, मैं बहुत खुश हूं कि मैंने इसके बारे में नहीं सोचा था। :-) मैं लूप को अपने स्वयं के ब्लॉक में रखना पसंद करता हूं। – Omnifarious

+0

उत्तर स्वीकार किया गया। फॉर-लूप के बाहर चर को परिभाषित करने और ब्रेसिज़ के बीच पूरे ब्लॉक को डालने से अधिक सुरुचिपूर्ण तरीका प्रतीत नहीं होता है। बॉक्स के बाहर सोचने के लिए – Patrick

+3

+1! लेकिन हाँ, बदसूरत! :-) –

2

कम से कम सी ++ हमें अगर खंड है, जो जो कभी कभी एक चर है कि केवल केवल दिख रहा है जब कुछ हालत सच है की घोषणा करने के लिए किया जाता है में चर घोषित करने के लिए अनुमति देता है:

if (MyElement *ptr=Pool->First) // block is only entered when ptr!=0 
{ 
for (int myIndex=0;ptr;++myIndex,ptr=ptr->next) 
{ 
} 
} 
// ptr is out of scope now. 

यह एक हो सकता है पठनीयता बनाए रखने के दौरान, पीआरटी और सूचकांक के दायरे को सीमित करने के लिए विधि।

+0

अगर कथन के लिए वास्तव में कोई ज़रूरत नहीं है। आप ब्रेसिज़ (लगभग) कहीं भी जोड़ सकते हैं जहां आप एक नया दायरा स्थापित करना चाहते हैं। –

+0

'if() के लिए() ... 'पैटर्न मैक्रोज़ के साथ भी अच्छी तरह से काम करता है। –

8

अगर मैं वास्तव में पाश के लिए गुंजाइश मैं का प्रयोग करेंगे सीमित करने के लिए चाहता था:

#include <utility> 
for (auto i = std::make_pair(0,Pool->First); 
    i.second; 
    ++i.first, i.second=i.second->next) 
+0

लेकिन अब आप वेरिएबल्स नामों द्वारा दी गई सारी जानकारी खो देते हैं: 'i.first' और 'i.second' चर के उद्देश्य के बारे में कोई जानकारी नहीं देते हैं, जबकि' myIndex' और 'ptr' कुछ देते हैं (बहुत कुछ नहीं, लेकिन कुछ)। –

+2

हां, यहां बनाने के लिए एक ट्रेडऑफ है - मैं कहूंगा कि यह जोड़ी का उपयोग करते समय मानक ट्रेडऑफ है। यदि जोड़ी के सदस्यों का उद्देश्य स्पष्ट है तो मैं जोड़ी के साथ रहूंगा। यदि नहीं, तो मैं स्पष्ट नामों के साथ समाधान पर स्विच करूंगा। –

+0

@LucTouraille: आप हमेशा std :: pair <> के स्थान पर इसके लिए एक छोटी सी संरचना को परिभाषित कर सकते हैं। – lorro

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