2010-02-18 2 views
20

एक अनंत लूप को लागू करते समय, while(1) बनाम for(;;) बनाम goto का उपयोग करने में कोई अंतर है?एक अनंत लूप को लागू करते समय, (1) बनाम (;;) बनाम गोटो (सी में) का उपयोग करने में कोई अंतर होता है?

धन्यवाद, Chenz

+1

मैं हमेशा उपयोग करता हूं। मुझे ऐसे तरीके से निर्मित लूप में कोई बिंदु नहीं दिखता है। यह सिर्फ एक व्यक्तिगत वरीयता है। (मुझे लगता है कि मुझे लापता होने की जानकारी है, जबकि जबकि लूप (मेरे लिए) अधिक सौंदर्यपूर्ण रूप से प्रसन्न दिखता है) – Tim

+0

तकनीकी रूप से, 1 में थोड़ी देर एक शर्त है जिसे प्रत्येक पुनरावृत्ति पर परीक्षण किया जाना चाहिए। मुझे विश्वास है कि सभी आम कंपाइलर्स एक सशर्त के बजाय उस से बाहर निकलने के लिए पर्याप्त स्मार्ट हैं। इसके अलावा, वे शैली के अलावा सभी समकक्ष हैं। – falstro

+3

कौन सा अनंत लूप दूसरे की तुलना में तेज़ है? – Anonym

उत्तर

44

वे समकक्ष हैं, भले ही आप ऑप्टिमाइज़र को बंद कर दें।

उदाहरण:

#include <stdio.h> 

extern void f(void) { 
    while(1) { 
     putchar(' '); 
    } 
} 

extern void g(void) { 
    for(;;){ 
     putchar(' '); 
    } 
} 

extern void h(void) { 
    z: 
     putchar(' '); 
    goto z; 
} 

gcc -O0 साथ संकलित सभी 3 कार्यों के लिए बराबर विधानसभा देता है:

# cat while.c 
int main() { 
    while(1) {}; 
    return 0; 
} 

# cat forloop.c 
int main() { 
    for (;;) { }; 
    return 0; 
} 

कोडांतरक करें:

f: 
; [ EXTERNAL ] 
; 
+00000 00000fb4 80402DE9    stmdb    sp!,{r7,lr} 
+00004 00000fb8 00708DE2    add    r7,sp,#0x0 
+00008 00000fbc 2000A0E3 loc_000008: mov    r0,#0x20 
+0000c 00000fc0 0A0000EB    bl    putchar (stub) 
+00010 00000fc4 FCFFFFEA    b     loc_000008 
; 
; 
g: 
; [ EXTERNAL ] 
; 
+00000 00000fc8 80402DE9    stmdb    sp!,{r7,lr} 
+00004 00000fcc 00708DE2    add    r7,sp,#0x0 
+00008 00000fd0 2000A0E3 loc_000008: mov    r0,#0x20 
+0000c 00000fd4 050000EB    bl    putchar (stub) 
+00010 00000fd8 FCFFFFEA    b     loc_000008 
; 
; 
h: 
; [ EXTERNAL ] 
; 
+00000 00000fdc 80402DE9    stmdb    sp!,{r7,lr} 
+00004 00000fe0 00708DE2    add    r7,sp,#0x0 
+00008 00000fe4 2000A0E3 loc_000008: mov    r0,#0x20 
+0000c 00000fe8 000000EB    bl    putchar (stub) 
+00010 00000fec FCFFFFEA    b     loc_000008 
+8

+1 :-) –

+0

ऑब्जेक्ट फ़ाइल से इस विशिष्ट असेंबली आउटपुट को उत्पन्न करने के लिए किस कमांड का उपयोग किया गया था? – bzeaman

0

मैं क्या मेरी "वियोजन साल" की याद से, यह बहुत एक फर्क नहीं होगा (compilers स्मार्ट पर्याप्त हैं)। यह सौंदर्यशास्त्र आईएमओ के बारे में अधिक है।

2

सी में, true के रूप में (संकलक पर निर्भर करता है)

#define TRUE 1 

या

#define TRUE (-1) 

और झूठे के रूप में

#define FALSE 0 

कार्यान्वित किया जाता है इस प्रकार कार्यान्वित किया जाता है तो while (1)while (true) के बराबर है चूंकि 0 को झूठा माना जाता है।

while (1) == for (; ;) क्योंकि कोई रोक स्थिति नहीं है।

जो

:loop 
    ... 
    ... 
    ... 
    goto loop 

तो कोडांतरक कोड एक ret या exit अनुदेश नहीं है, तो के रूप में कोडांतरक के लिए अनुवाद किया है, यह एक अनंत लूप माना जाता है।

6

मैं सिर्फ जीसीसी के unoptimized कोडांतरक उत्पादन की तुलना में आउटपुट:

# gcc -S while.c 
# gcc -S forloop.c 

कोडांतरक फ़ाइलों की तुलना करें:

# diff forloop.s while.s 
1c1 
< .file "forloop.c" 
--- 
> .file "while.c" 

तुम वहाँ कोई महत्वपूर्ण मतभेद हैं देख सकते हैं। यहाँ उत्पादन

# cat while.s 
    .file "while.c" 
    .text 
.globl main 
    .type main, @function 
main: 
    pushl %ebp 
    movl %esp, %ebp 
.L2: 
    jmp .L2     # this is the loop in both cases 
    .size main, .-main 
    .ident "GCC: (GNU) 4.4.3" 
    .section .note.GNU-stack,"",@progbits 

है जबकि यह एक तकनीकी सबूत है कि वे एक ही कर रहे हैं नहीं है, मैं यह कहना चाहता हूँ यह मामलों की 99.9% है।

3

कोई नहीं। उपयोग करें जो आपके लिए सबसे अधिक पढ़ने योग्य है

4

जेनरेट असेंबली में शायद ही कोई अंतर है।यह एक शैलीगत मुद्दे के अधिक है:

गोटो - बस ooogly: पिछड़े कोई स्पष्ट अनंत ब्लॉक कूदता है,

जबकि (1) - बेहतर की आवश्यकता है "डमी" हालत हालांकि और आप अक्सर हो जाएगा संकलक (चेतावनी स्तर 4) या स्थिर विश्लेषण उपकरण

के लिए (;;) सुंदर होना नहीं हो सकता है ने चेतावनी दी है, लेकिन imho सबसे अच्छा फिट बैठता है क्योंकि इस संरचना किसी अन्य अर्थ (जबकि की तुलना में) नहीं हो सकता। लेकिन कुछ अन्य लोगों, जबकि (1) "एक ही" कारण के लिए ...

2

हालांकि कोई महत्वपूर्ण अंतर अन्य पदों में उल्लेख किया है के रूप में वहाँ है, एक आम कारण for (;;)while (1) के बजाय का उपयोग करना पसंद है कि स्थिर विश्लेषण उपकरण (और कुछ चेतावनी स्तर वाले कुछ कंपाइलर) अक्सर लूप के बारे में शिकायत करते हैं।

गोटो थोड़ा बुरा है, लेकिन दूसरों के समान कोड बनाना चाहिए। निजी तौर पर, मैं for (;;) (लिंट को खुश रखने के लिए) तक रहता हूं, लेकिन मुझे while (1) के साथ कोई समस्या नहीं है।

3

while(1) और for(;;) बिल्कुल समकक्ष हैं और दोनों अनंत लूप कोड को अच्छी तरह से समझने वाले मुहावरे हैं।

मैं goto के उपयोग से बचूंगा: एक अनंत लूप से तोड़ने के लिए या अगले पुनरावृत्ति पर आगे बढ़ने के लिए, break और continue का उपयोग करें।

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