2012-01-10 12 views
40

ज्यादातर मज़ा/जिज्ञासा के लिए एक सवाल लिखने के लिए कैसे: कैसे C++ कि एक bool (यानी true और false) के दो मूल्यों पर पुनरावृति होगी एक for पाश लिखने के लिए , bool (यानी अन्य प्रकारों के रूपांतरण के बिना) के साथ केवल संचालन का उपयोग कर? अर्थात क्या हालत पाश जारी रखने के लिए होगा -bool मूल्यों पर एक `for` पाश (गलत और सही)

पृष्ठभूमि है कि मैं जाँच करने के लिए कितने समाधान (A && B) || (!B && !C && !D) == true की तरह एक समीकरण के लिए मौजूद थे, और for (bool A=false; ??? ; ++A) for (bool B=false; ...) आदि की तरह कुछ लिखने के लिए शुरू किया, लेकिन तुरंत ??? से अटक गया है? बेशक मैं इसे int का उपयोग करने के लिए पुनः लिखता हूं, और मुझे यह भी पता है कि do ... while लूप काम करेगा, लेकिन अगर मुझे for लूप लिखना संभव हो तो मुझे उत्सुकता हो रही है? ध्यान दें, कि एक "स्पष्ट" संस्करण for(bool A=false; !A; A=true) कम से कम दो अब हटा दिया जवाब में सुझाव दिया केवल एक यात्रा चलेंगे क्योंकि: और इतने के बाद से एक जवाब है नहीं लगता है, मैं पूछने के लिए :)


अद्यतन का फैसला किया दूसरे के लिए स्थिति !Afalse बन जाती है और लूप समाप्त होता है।

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

+2

यह आश्चर्यजनक है कि गलत उत्तरों को कितनी जल्दी हटा दिया जाता है! –

+1

हां, जब आप ऐसा करते हैं तो आप इससे नफरत नहीं करते? मुझे यह एक अच्छा सवाल है। मैं ऊपर उठाया। –

+0

क्योंकि यह साइट मजेदार/जिज्ञासा के लिए नहीं है। असली सवाल! पीएस नहीं, यह मैं नहीं था, मैं भी उत्सुक हूँ। –

उत्तर

48

सी ++ 11 में: for (bool b : { false, true }) { /* ... */ }


यहाँ एक सी ++ 03 संस्करण है: (। या तो a या b का प्रयोग करें)

for (bool a = true, b = false; b != a; a = a && b, b = !b) { /*...*/ } 

+1

यह प्रारंभकर्ता सूची के साथ एक दिलचस्प संस्करण है। – Xeo

1

यह एक काम करता है , भी:

for (bool a = false, b = false; a == b; b = !b, a = a || b) { } 

(@ KerrekSB की तुलना में औंधा समाधान की तरह)

6

जब आप एक दृष्टिकोण मोटे तौर पर सी ++ 2011 दृष्टिकोण के बराबर इस्तेमाल कर सकते हैं सी ++ 2003 तक प्रतिबंधित;

{ 
    bool const bools[] = { false, true }; 
    for (bool const* it(bools); it != std::end(bools); ++it) { 
     bool a(*it); 
     use(a); 
    } 
} 

संभावित रूप से एक मैक्रो में पैक किया गया। तुम भी के लिए सी ++ 03

for (bool a: { false, true }) { 
    use(a); 
} 
+0

मुझे लगता है कि आप संभवतः उस सरणी को लूप के घोषणापत्र भाग में पैक कर सकते हैं। हालांकि यकीन नहीं है। – Xeo

+0

आपका जादू 2 पूरे विचार के विपरीत है। – Wolf

+1

@ वुल्फ: प्रतिक्रिया 2012 में लिखी गई थी। मुझे लगता है कि, पिछले मुझे सी ++ 11 आम तौर पर उपलब्ध नहीं माना गया था (हालांकि मैंने 'std :: end()' -1998 को लागू करने के लिए आवश्यक कार्यक्षमता की खोज की। –

2

एक और उपयोग कर सकते हैं:

for(bool a = false, b = true; b; a = !a, b = a) 

उपयोग ज।

4
for (int a = 0; a <= 1; a++) 
    doStuff(a ? true : false); 

और के बारे में "अन्य प्रकार की कोई रूपांतरण" प्रतिबंध :) दिन स्पष्टता के अंत में भूल जाते हैं कृत्रिम प्रतिबंध से ज्यादा महत्वपूर्ण है। लाइन के नीचे पांच साल आप अपना खुद का कोड पढ़ेंगे और सोचेंगे कि "मैं क्या बिल्ली सोच रहा था, क्या यह किसी प्रकार का अपवित्रता प्रतियोगिता है?"

+0

यदि आप 'int' के बजाय' char' /' uint8_t' का उपयोग करते हैं, तो एक अच्छा मौका है कि वे उसी अंतर्निहित डेटाटाइप में संकलित होंगे और आपको शून्य लागत कास्टिंग देता है। –

+0

@ SlippD.Thompson यह 'doStuff' पर निर्भर करता है कि' int' कुशल है या नहीं। – Wolf

4
a = true; 
do { 
    use(a); 
    a = !a; 
} while (!a); 

ठीक है, तो यह नहीं पाश के लिए एक है, लेकिन मैं यह पाश सुझाव के लिए में से किसी की तुलना में अधिक पठनीय है तर्क है (, सी ++ 11 दृष्टिकोण के अलावा अन्य कोर्स की।)

+0

लूप के अंदर 'जारी रखें' काम को अपेक्षित करने के लिए: 'a = false; करें {...} जबकि (ए =! ए); '। चर/स्थिर में प्रारंभिक मान: 'a = init; करें {...} जबकि (init! = (ए =! ए)); ' – adf88

2

यह जवाब है "असंभव" सी ++ 03, एकल चर एकमात्र समाधान

प्रथम पते, हमें इस बात की पुष्टि है कि कोई नियतात्मक अंकगणितीय अभिव्यक्ति एक भी इनपुट चर पर केवल भरोसा दोनों आदानों true,false लेकिन फिर नहीं के लिए सही हो सकता है एक तीसरे मान के लिए जो true या false में से एक होना चाहिए ।

हालांकि, हम "धोखा" सकते हैं। हालांकि, मैं आपको यह साबित करने के लिए आग्रह करता हूं कि मैं वास्तव में धोखा दे रहा हूं।

#include <iostream> 

using namespace std; 

int main() { 
    for (bool b = false; *((char*)&b) != 2; *((char*)&b) += 1) { 
     cout << "bool " << b << endl; 
    } 
} 

यह निश्चित रूप अपरिभाषित व्यवहार की तरह लगता है। सी ++ 03 थोड़ा unclear about it है। हालांकि, sizeof हमेशा कम से कम 1 होना चाहिए (0-लंबाई वाले var-len arrays के लिए गैर-मानक अपवाद के साथ)। इसके अलावा, चूंकि हम गारंटी देते हैं कि प्रत्येक चार कम से कम 8 बिट्स है, हम दूसरे काउंटर के लिए दूसरे का उपयोग कर सकते हैं।

वास्तव में, ऐसा करने के लिए हमें या तो स्कर्ट निर्धारणवाद की आवश्यकता है (गारंटी को छोड़कर हम false, true पर एक बार फिर से शुरू नहीं कर सकते हैं) या हमारी बाध्यकारी प्रकार प्रणाली।

0

मुझे पता है कि आपने दूसरे प्रकार के रूपांतरण के बिना समाधान के लिए कहा है, लेकिन मुझे लगता है कि आपका मतलब है कि "बिना किसी अन्य प्रकार के रूपांतरण के रूपांतरण"। इस विशिष्ट मामले में bool को प्रतिस्थापित करने वाली ऑब्जेक्ट की पेशकश करने का उत्तर यहां दिया गया है।

struct IterableBool 
{ 
    bool b; 
    bool out_of_scope; 
    IterableBool() : b(false), out_of_scope(false) {} 
    IterableBool(bool b_) : b(b_), out_of_scope(false) {} 
    IterableBool(IterableBool ib) : b(ib.b), out_of_scope(ib.out_of_scope) {} 
    operator bool() { return this->b; } 
    bool in_scope() const { return !this->out_of_scope; } 
    IterableBool& operator ++() 
    {      
    this->out_of_scope = this->b; 
    this->b = true; 
    return *this; 
    } 
    IterableBool operator ++ (int) 
    { 
    IterableBool copy = *this; 
    ++(*this); 
    return copy; 
    } 
    IterableBool& operator --() 
    { 
    this->out_of_scope = !this->b; 
    this->b = false; 
    return *this; 
    } 
    IterableBool operator -- (int) 
    { 
    IterableBool copy = *this; 
    --(*this); 
    return copy; 
    } 
}; 

// Usage : 
for(IterableBool ib = false; ib.in_scope(); ++ib) 
    do_stuff((bool)ib);