2012-03-16 14 views
26

मैं कुछ सी कोड लिख रहा हूं और मेरे कोड में मेरे पास दो नेस्टेड लूप हैं। एक विशेष स्थिति पर मैं आंतरिक लूप और continue बाहरी लूप से break करना चाहता हूं। मैंने बाहरी लूप के कोड पर अंत में एक लेबल का उपयोग करके इसे प्राप्त करने का प्रयास किया, और उस स्थिति पर, goto लेबल। हालांकि gcc एक त्रुटि देता है कि मेरे पास यौगिक कथन के अंत में एक लेबल नहीं हो सकता है। क्यों नहीं?सी में आपको गोटो लेबल के बाद एक कथन की आवश्यकता क्यों है?

नोट 1: यह एक switch बयान और कि सवाल का जवाब दे दिया गया है elsewhere नहीं है।

नोट 2: यह शैली के बारे में कोई सवाल नहीं है और क्या मुझे इसके बजाय goto कथन या सशर्त चर का उपयोग करना चाहिए या नहीं करना चाहिए।

संपादित करें: लोग एक उदाहरण के लिए कहा है और यदि एक सरणी एक और सरणी के एक subarray

int superArray[SUPER_SIZE] = {...}, subArray[SUB_SIZE] = {...}; 
    int superIndex, subIndex; 

    for (superIndex=0; superIndex<SUPER_SIZE-SUB_SIZE; superIndex+=1) 
    { 
     for (subIndex=0; subIndex<SUB_SIZE; subIndex+=1) 
     if (superArray[superIndex+subIndex] != subArray[subIndex]) 
      goto break_then_continue; 

     // code that executes if subArray is a sub array 

     break_then_continue: 
    } 
+3

यदि आप एक छोटे प्रोग्राम है जो आप प्राप्त त्रुटि संदेश reproduces दे सकते हैं? – sarnold

+0

अच्छी किस्मत और velociraptors के लिए बाहर देखो – wim

उत्तर

34

मानक में यह स्पष्ट रूप से कहा गया है कि लेबल एक बयान के हैं, इसलिए एक सरल अर्धविराम (;) के बाद अपने लेबल उस समस्या को बाधित कर सकता है जिसमें आप चल रहे हैं, क्योंकि यह एक कथन के रूप में गिना जाता है।

भी 6.8.3/6 में एक "खाली" बयान के उपयोग का एक उदाहरण है।

उदाहरण 3 एक अशक्त बयान भी सिर्फ एक यौगिक बयान

while (loop1) { 
    /* ... */ 

    while (loop2) { 
    /* ... */ 

    if (want_out) 
     goto end_loop1; 

    /* ... */ 
    } 

    /* ... */ 

    end_loop1: ; 
} 

के समापन} इस मानक में से पहले एक लेबल ले जाने के लिए इस्तेमाल किया जा सकता में जाना जाता है के रूप में।


6.8.1 लेबल लगाए गए बयान

Syntax 
    1 labeled-statement: 
     identifier : statement 
     case constant-expression : statement 
     default : statement 

सूचना है कि statement ऊपर उद्धरण में वैकल्पिक नहीं है।


+0

+1 ग्रेट उत्तर। सीधे मानक से लिया उदाहरण प्यार करें। – Caleb

+0

महान प्रतिक्रिया के लिए धन्यवाद। मैं देख रहा था * क्यों * 'gcc' इस तरह से काम करता है कि यह कैसे नहीं मिलता है। हालांकि आपकी प्रतिक्रिया यह इंगित करती है कि सी सी लिखा गया है। यह काफी हद तक एक विरासत है जब सी संकलन असेंबली कोड का केवल मामूली अमूर्त था। – AntonDelprado

+0

@ एंटोन डेलप्रैडो यह वास्तव में बहुत आसान है, गेटो कमांड/अभिव्यक्ति से पहले लेबल रखेगा और यदि ऐसी कोई बात नहीं है, तो वहां कूदने के लिए कहीं भी नहीं है। वह खाली कथन का उपयोग किया जाता है, इसलिए यह संभव है। इस तरह आप एनओपी (कोई ऑपरेशन) असेंबली फ़ंक्शन के कुछ हानिरहित समकक्ष पर कूदते हैं। – AoeAoe

3

आप बस लिखने की ज़रूरत है मैं जाँच का थोडा सा सतही उदाहरण दे सकते हैं:

label: ; 

अर्ध-कॉलन एक खाली बयान है। आपको इसकी आवश्यकता है क्योंकि भाषा इस तरह परिभाषित है; आपको एक बयान में जाना होगा, भले ही यह खाली हो।

for (int i = 0; i < N; i++) 
    { 
     for (int j = 0; i < M; j++) 
     { 
      ... 
      if (some_condition) 
       goto continue_loop1; 
      ... 
     } 
continue_loop1: ; 
    } 

आप लेबल पर खरोज के बारे में लोगों का तर्क कर सकते हैं।

+0

यह भी ध्यान दें कि एक प्रारंभिकरण के साथ भी एक घोषणा, एक कथन नहीं है जिसे लेबल किया जा सकता है: 'लेबल 1: int x = function (y, z); 'मान्य नहीं है। –

3

लेबल एक बयान इंगित करना चाहिए।

सी जनादेश इस:

(C99, 6.8.1 लेबल लगाए गए बयान पी 4) " किसी भी बयान एक उपसर्ग है कि एक लेबल नाम के रूप में पहचान करने की वाणी से पहले हो सकता है।"

अपने मामले में आप एक अशक्त कथन का उपयोग कर सकते हैं:

void foo(void) 
{ 
    goto bla; 

    bla: 
    ; 
} 

अशक्त बयान कोई कार्रवाई करने के।

या आप भी एक यौगिक बयान (एक ब्लॉक) यदि आप घोषणाओं का उपयोग कर सकते हैं:

void foo(void) 
{ 
    goto bla; 

    bla: 
    { 
     int x = 42; 
     printf("%d\n", x); 
    } 
} 
संबंधित मुद्दे