2009-07-24 1 views

उत्तर

23
+20

+1 हालांकि, यदि आप किसी केस लेबल के लिए कथन लपेटने के लिए {...} का उपयोग करके नेस्टेड स्कोप बना सकते हैं। –

0

खैर है अगर मैं स्विच बयान यह ठीक काम करता है से पहले चर घोषणा डाल दिया। मुझे लगता है कि उद्देश्य सी में परिवर्तनीय घोषणाएं 'अभिव्यक्ति' नहीं हैं?

2

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

तो:

switch (foo) { 
    case 0: { 
     // notice explicit scope here 
     break; 
    } 
    default: { 
     // here as well 
    } 
} 
1

मैंने पहले इस समस्या को देखा है। इसे सी में लेबल के साथ करना है, और गेटोस के लिए इस्तेमाल किए गए लेबल पर भी लागू होगा। केस 1 :, केस 2: लाइनें लेबल हैं। किसी भी कारण से, लेबल के बाद पहला कथन एक घोषणा नहीं होना चाहिए। यदि कोई और कोई अच्छा जवाब नहीं देता है तो मैं कुछ जानकारी के साथ कुछ शोध और अद्यतन करूंगा।

5

एक चीज जो मुझे इस स्थिति में करना है वह है ब्रेसिज़ के भीतर प्रत्येक case की सामग्री डालना। यह संकलक द्वारा अनुमत है:

switch (buttonIndex) 
{ 
    case 0: 
    { 
     [actionSheet dismissWithClickedButtonIndex:buttonIndex animated:YES]; 
     break; 
    } 
    case 1: 
    { 
     UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; 
     imagePicker.delegate = self; 
     imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; 
     [self presentModalViewController:[imagePicker autorelease] animated:YES]; 
     break; 
    } 
    default: 
    { 
     [self openEmailViewInViewController:self]; 
    } 
} 
+1

नोट: सी में, आप कहीं भी कहीं भी अतिरिक्त ब्रेसिज़ डाल सकते हैं, जब तक उचित घोंसले संरक्षित किया जाता है। अगर (foo) {{{{{}}}}} // पूरी तरह से कानूनी है – Amagrammer

+0

आपके उत्तर के लिए धन्यवाद, इस प्रकार की सादगी इस साइट को इतना उपयोगी बनाती है! कीप आईटी उप। –

62

मैं इस समस्या में भाग गया, और एक दिन मैंने इसे खोदने का फैसला किया।

कम गैर-जवाब लेकिन व्यावहारिक समाधान:

एक तरह से इस "समस्या" के आसपास काम करने के लिए सही एक case ...: बयान के कोलन के बाद एक सेमी-कोलन, ;, उपयोग करने के लिए है। उदाहरण के लिए, उदाहरण आपके द्वारा दी गई उपयोग कर, यह कर सकते हैं "निर्धारित" हो तो यह संकलित करता है तथा आप सहज करने के लिए यह उम्मीद करेंगे के रूप में व्यवहार:

case 1:; // <- Note semi-colon. 
      UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init]; 
      imagePicker.delegate = self; 

विस्तृत उत्तर है:

कुछ इतिहास: पहले, केवल सी आपको ब्लॉक की शुरुआत में "स्थानीय ब्लॉक" चर घोषित करने की अनुमति दी गई, जिसके बाद विभिन्न वक्तव्यों का पालन किया गया। सी 99 ने चीजों को बदल दिया ताकि आप परिवर्तनीय घोषणाओं और बयानों को स्वतंत्र रूप से अंतःस्थापित कर सकें।

सी 99 बीएनएफ व्याकरण के संदर्भ में, एक परिवर्तनीय घोषणा declaration है, और एक कथन statement है। statement का अर्थ कई चीजें हैं, उनमें से एक को compound-statement के रूप में जाना जाता है, जो परिचित { ... } ब्लॉक है।... हिस्सा शिथिल एक block-item साथ, zero or moreblock-items के रूप में परिभाषित किया गया है either adeclarationor astatement के रूप में हल्के ढंग से परिभाषित किया जा रहा।

समस्या रास्ते में निहित एक labeled-statement (एक गोटो लेबल, मामले लेबल करने, या default:, अनिवार्य रूप से ...: बयान), परिभाषित जो शिथिल ...: zero or morestatements परिभाषित किया गया है है। यह न, के रूप में एक सहज उम्मीद कर सकते हैं, zero or morestatementsordeclarations है। का उपयोग labeled-statement s : के ठीक बाद zero or morestatementslabeled-statement का हिस्सा अनिवार्य रूप से समाप्त करता है। इससे व्याकरण compound-statement परिभाषा पर वापस आ जाता है, जो अगले "कथन" को statement या declaration होने की अनुमति देता है।

मैंने जांच नहीं की है कि यह सी 99 भाषा की कल्पना (व्यावहारिक रूप से, सी 99 मानक में एक बग) की अनजान दृष्टि से है या नहीं, या यदि यह भाषा व्याकरण लिखने की जटिलताओं के लिए व्यावहारिक रियायत है । यदि आप व्याकरण लिखने से परिचित नहीं हैं, तो आप देखेंगे कि उपरोक्त स्पष्टीकरण रिकर्सन के लिए अनुमति देता है: labeled-statementcase 1: case 2: case 3: से मेल खा सकता है। अत्यधिक सरल शब्दों में (1), कुछ प्रकार के व्याकरण रिकर्सन सरल और "स्पष्ट" हैं, जबकि अन्य जटिल और "संदिग्ध" हैं। सादगी के लिए, अधिकांश भाषा औजार केवल उस मामले को संभाल लेंगे जहां "अगली टोकन" से अधिक कुछ भी नहीं देखकर किसी भी अस्पष्टता को निश्चित रूप से हल किया जाना चाहिए। मैं इसका केवल इसलिए उल्लेख करता हूं क्योंकि यह सहज रूप से सी 99 स्पेक में कमी की तरह प्रतीत हो सकता है, यह अनिवार्य, स्पष्ट कारण हो सकता है कि यह क्यों मौजूद है ... और मुझे इस विषय पर कोई और शोध करने के लिए परेशान नहीं किया गया है किसी भी तरह से।

(1) यह तकनीकी रूप से सटीक वर्णन नहीं है, लेकिन उन मुद्दों के बारे में उचित अनुमान नहीं है जो शामिल मुद्दों से परिचित नहीं हैं।

संपादित करें:

समाधान मैं (जा रहा है "उपयोगिताएं", नहीं switchcase रों मामले) "सबसे" मामलों में काम करता है दे दी है, लेकिन यह एक मामले में विफल करता है: यह जब काम नहीं करेगा घोषणापत्र एक सी 99 variable length array घोषित करता है, जैसे कि case 1:; void *ptrs[count]; ऐसा इसलिए है क्योंकि सी 99 में यह एक सी 99 वीएलए की घोषणा को "पिछली कूद" करने में एक त्रुटि है जो कि समान लेक्सिकल स्कोप में है जहां कूद हुआ था। इन मामलों में, आपको case 1: { void *ptrs[count]; } का उपयोग करने की आवश्यकता है। इस मामले में, ptrs वीएलए का दायरा } बंद होने पर समाप्त होता है।

switch(3){ 
    case 0: 
    printf("case 0\n"); 
    break; 
    case 1:; 
    int *ip = NULL; 
    printf("case 1\n"); 
    break; 
    case 2: 
    { 
     int ia[6]; 
     printf("case 2\n"); 
     break; 
     case 3: 
     printf("case 3\n"); 
     break; 
     default: 
     printf("default\n"); 
    } 
} 

यह संकलित है, और जब चलाने के लिए, प्रिंट case 3: यह और अधिक जटिल की तुलना में यह पहले दिखाई देती है क्योंकि निम्नलिखित पूरी तरह से कानूनी सी कोड है, हालांकि पहली नजर में एक सहज लगता होगा यह नहीं है।

यह भी देखें: Wikipedia: Duffs Device

+0

ठीक है, यह पहले से जानता था * I * से बहुत अधिक है। मुझे पता था कि किसी कारण से सी को उप-स्कोप की आवश्यकता होती है यदि आप किसी मामले में घोषणा करना चाहते हैं। धन्यवाद। – Amagrammer

+1

अरे, यह एक अच्छा जवाब है। –

+4

<धीमी गति से शुरू होता है> – griotspeak

3

मैं कभी कभी इस तरह की समस्या है।

के रूप में अजीब यह लग सकता है, के बाद मैं त्रुटि से पहले एक NSLog जोड़ने के लिए, यह काम करता है

संपादित करें: सी भाषाओं में आप नहीं एक स्विच में instanciate वस्तुओं आप हर डाल नहीं करता है, तो कर सकते हैं "मामले "के बीच {} s