क्या लूप के अंदर एक वैरिएबल को परिभाषित करना अच्छा है? [बन्द है]


15

मेरे प्रशिक्षक ने एक बार मुझसे कहा था कि मुझे एक लूप के अंदर एक वैरिएबल को परिभाषित नहीं करना चाहिए , लेकिन मैं ईमानदारी से अभी भी नहीं समझ पा रहा हूं कि क्यों।

उस के नुकसान क्या हैं?

क्या कोई शरीर मुझे समझा सकता है?


7
आपका प्रशिक्षक किस प्रोग्रामिंग भाषा को सिखा रहा था?
ब्रायन

2
यदि आप लूप में एक गैर-आदिम प्रकार के साथ एक चर को परिभाषित करते हैं, तो आपका प्रोग्राम हर बार अपने निर्माता को लूप के माध्यम से कॉल करने की आवश्यकता को समाप्त कर सकता है। यदि आपको केवल लूप के बाहर एक बार इसे परिभाषित करने की आवश्यकता है, तो ऐसा करें।
ब्रैंडिन

17
जब आपको प्रशिक्षक के बारे में ऐसी उलझन होती है, तो सबसे अच्छा संसाधन प्रशिक्षक से पूछ रहा है। वे आपको आगे और पीछे का संचार दे सकते हैं जो एक प्रश्नोत्तर साइट प्रदान नहीं कर सकती है।

1
क्रॉस-साइट डुप्लिकेट: पहले या पाश में घोषित चर के बीच अंतर? (और निश्चित रूप से कई, इस तरह के एक प्राथमिक प्रश्न के लिए उस साइट पर कई डुप्लिकेट हैं (केवल सी ++ के बारे में हैं) सहित।
पीटर मोर्टेनसेन

2
यह सलाह एक संदर्भ के लिए विशिष्ट थी। व्यक्तिगत शैली के रूप में, मैं अपने चरों की घोषणा करना पसंद करता हूं constजब तक कि कोई कारण न हो (कार्यात्मक प्रोग्रामिंग से एक आदत)। या तो मैं उन्हें संशोधित नहीं करूंगा, और ऑप्टिमाइज़र को पता लगाना चाहिए कि उन्हें कब ज़रूरत नहीं है, या मैं करूँगा और मैंने एक गंभीर बग को रोका है। जब वे निरंतर मध्यवर्ती मान लूप के पुनरावृत्ति के लिए विशिष्ट होते हैं, तो इसका अर्थ है कि उन्हें लूप के अंदर घोषित करना। एक और समय जब आपको लूप के बाहर चर घोषित करने की आवश्यकता होती है, हालांकि, जब आप लूप के बाहर उन्हें संदर्भित करेंगे; उदाहरण के लिए, आप जो परिणाम संग्रहीत कर रहे हैं।
डेविसलर

जवाबों:


42

यह एक लूप के भीतर एक चर को परिभाषित करने के लिए एक समस्या नहीं है । वास्तव में, यह अच्छा अभ्यास है, क्योंकि पहचानकर्ता को सबसे छोटे संभव दायरे तक ही सीमित होना चाहिए।

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

स्पष्ट करने के लिए: जब तक compute()हमेशा एक ही मूल्य वापस नहीं आता, यह

int value = compute();
while (something) {
    doSomething(value);
}

इससे अधिक स्मार्ट है:

while (something) {
    int value = compute();
    doSomething(value);
}

2
आप लूप में एक चर को कैसे परिभाषित करेंगे और इसे लूप से पहले असाइन करेंगे?
मानस

6
@MaskedMan, मुझे लगता है कि आप गलत समझ रहे हैं। काइलियन का क्या मतलब है यदि आपके पास एक ऐसा चर है जिसे लूप के प्रत्येक पुनरावृत्ति के दौरान समान मान असाइन किया गया है, उदाहरण के लिए, उसी दिनांक चर को सेट किया गया है 1/1/1900, चर घोषित किया जाना चाहिए और लूप से पहले मान असाइन किया जाना चाहिए।
ps2goat

2
मुझे नहीं लगता कि पिछले बीस वर्षों (अंडरग्राउंड कंपाइलर कोर्स के बाहर) में एक कंपाइलर लिखा गया है, जो यह पता नहीं लगाएगा कि आप प्रत्येक पुनरावृत्ति पर समान मान असाइन कर रहे हैं और उस असाइनमेंट को लूप से बाहर ले जाते हैं।
TMN

14
@ टीएमएन: कभी भी एक कंपाइलर को ऐसा न करें जो आप अपने आप को अधिक कोड स्पष्टता के साथ तुच्छ रूप से कर सकें।
रॉबर्ट हार्वे

10
@ टीएमएन, जरूरी नहीं। यह अनुकूलन केवल तभी संभव है जब कंपाइलर साबित कर सकता है कि गणना साइड-इफ़ेक्ट फ्री है।
पॉल ड्रेपर

16

जटिल प्रकारों में गैर-तुच्छ निर्माता और विध्वंसक होते हैं।

लूप बॉडी के शुरू और अंत में उन लोगों को बुलाया जाएगा (जैसा कि इसे आरंभीकृत किया गया है और यह दायरे से बाहर हो जाता है)। यदि इनिशियलाइज़ेशन महंगा है जैसे कि इसे कुछ मेमोरी आवंटित करने की आवश्यकता है तो इससे बचा जाना चाहिए।

हालांकि तुच्छ प्रकार के लिए जो कोई समस्या नहीं है। आबंटन और डीलक्लोकेशन केवल स्टैक पॉइंटर से एक मूल्य जोड़ और घटा रहा है। (जो बाहर अनुकूलित हो जाएगा)


धन्यवाद, बिल्कुल जवाब मैं देख रहा था!
गब्बिसिमो

6

खैर, उनकी सलाह थोड़ी सरल है (यह एक ख़ामोशी है)।
इससे सभी तरह पर्वतमाला के बाद एक अच्छा विचार से अधिक कौन परवाह करता है और बुरा विचार करने के लिए असंभव

  1. जब भी पुन: उपयोग करना पुराने को नष्ट करने और नया बनाने की तुलना में सस्ता है, तो आपको इसका पालन करना चाहिए।

    #include <iostream>
    #include <string>
    
    int main() {
        std::string s; // Don't needlessly free the buffer
        while ((std::cin >> s))
            std::cout << s;
    }
  2. जब इसे प्रदर्शन के लिए कोई फर्क नहीं पड़ता, तो आपको इसे शैली की बात के रूप में छोड़ देना चाहिए।

    #include <stdio.h>
    #include <stdlib.h>
    int f(int, int);
    
    int main() {
        for (int i = 0; i < 100; ++i) {
            int x = rand(); // Declared here so you don't need to hunt it down.
            printf("%d => %d\n", x, f(x-1, x+i));
        }
    }
  3. आपको वास्तव में इसे तब करना चाहिए जब इसका प्रदर्शन खराब हो या गलत शब्दार्थ हो।

    #include <iostream>
    #include <string>
    std::string generate(int);
    
    int main() {
        for(int i = 0; i < 100; ++i) {
            std::string s = generate(i); // Using copy-ellision here
            std::cout << s;
        }
    }
  4. आप इसका उपयोग तब नहीं कर सकते जब इस्तेमाल किया गया प्रकार न तो स्वैपिंग की अनुमति देता है, न ही मूव-असाइनमेंट और न ही कॉपी-असाइनमेंट।

    #include <iostream>
    #include <puzzle>
    
    int main() {
        for (int i = 0; i < 100; ++i) {
            Puzzle x(i); // Puzzle is an immutable class. For whatever reasons.
            std::cout << x;
        }
    }

2
"एक पाश में" की आपकी परिभाषा के आधार पर, 1 को बदल दिया जा सकता है for (std::string s; std::cin >> s;) ...और फिर भी "बाहर" हो सकता है
Caleth
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.