क्या C ++ 03 में 'ऑटो' कीवर्ड का उपयोग करने का कोई कारण है?


85

ध्यान दें कि यह प्रश्न मूल रूप से 2009 में पोस्ट किया गया था, इससे पहले कि C ++ 11 की पुष्टि की गई थी और autoकीवर्ड के अर्थ में काफी बदलाव किया गया था। प्रदान किए गए उत्तर केवल C ++ 03 से संबंधित हैं auto- जिसका अर्थ है कि एक स्टोरेज क्लास निर्दिष्ट होना - और C ++ 11 का अर्थ नहीं है auto- जो कि स्वचालित प्रकार की कटौती है। यदि आप C ++ 11 का उपयोग करने के बारे में सलाह की तलाश कर रहे हैं auto, तो यह प्रश्न उस प्रश्न के लिए प्रासंगिक नहीं है।

सबसे लंबे समय तक मैंने सोचा था कि staticसी में कीवर्ड का उपयोग करने का कोई कारण नहीं था , क्योंकि ब्लॉक-स्कोप के बाहर घोषित किए गए चर स्पष्ट रूप से वैश्विक थे। तब मुझे पता चला कि staticब्लॉक-स्कोप के भीतर एक वैरिएबल घोषित करने से इसे स्थायी अवधि मिलेगी, और इसे ब्लॉक-स्कोप (प्रोग्राम-स्कोप में) के बाहर घोषित करने से इसे फाइल-स्कोप मिलेगा (केवल उस संकलन इकाई में पहुँचा जा सकता है)।

इसलिए यह मुझे केवल एक कीवर्ड के साथ छोड़ता है जिसे मैं (शायद) अभी तक पूरी तरह से नहीं समझता: autoकीवर्ड। क्या 'स्थानीय चर' के अलावा इसका कुछ और अर्थ है? कुछ भी ऐसा नहीं है जो आपके लिए निहित नहीं है, जहाँ भी आप इसका उपयोग करना चाहते हैं? autoप्रोग्राम के दायरे में एक चर कैसे व्यवहार करता है ? static autoफ़ाइल-स्कोप में एक चर क्या है ? क्या इस कीवर्ड का पूर्णता के लिए मौजूदा के अलावा कोई उद्देश्य नहीं है ?

जवाबों:


74

autoएक भंडारण वर्ग विनिर्देशक है static, registerऔर externभी। आप घोषणा में केवल इन चार में से किसी एक का उपयोग कर सकते हैं।

स्थानीय चर (बिना) static ) की स्वचालित भंडारण अवधि होती है, जिसका अर्थ है कि वे अपनी परिभाषा की शुरुआत से अपने ब्लॉक के अंत तक रहते हैं। ऑटो को उनके सामने रखना बेमानी है क्योंकि यह वैसे भी डिफ़ॉल्ट है।

मैं इसे C ++ में उपयोग करने का कोई कारण नहीं जानता। पुराने C संस्करणों में जिसका निहित अंतर नियम है, आप इसका उपयोग किसी चर को घोषित करने के लिए कर सकते हैं, जैसे:

int main(void) { auto i = 1; }

मामले में एक असाइनमेंट एक्सप्रेशन से वैध सिंटैक्स या डिसएम्बीग करना iहै। लेकिन यह सी ++ में वैसे भी काम नहीं करता है (आपको एक प्रकार निर्दिष्ट करना होगा)। काफी मजेदार, C ++ मानक लिखते हैं:

ब्लॉक-स्कोप पर स्टोरेज-क्लास-स्पेसिफ़ायर के बिना घोषित या फ़ंक्शन पैरामीटर के रूप में घोषित ऑब्जेक्ट में डिफ़ॉल्ट रूप से स्वचालित संग्रहण अवधि होती है। [नोट: इसलिए, ऑटो स्पेसियर लगभग हमेशा बेमानी है और अक्सर उपयोग नहीं किया जाता है; ऑटो का एक उपयोग अभिव्यक्ति-बयान (6.8) से स्पष्ट रूप से घोषणा-बयान को अलग करना है। - अंतिम नोट]

जो इस परिदृश्य पर, जो या तो की एक डाली हो सकता है को संदर्भित करता है aके लिए intया एक चर की घोषणा aप्रकार के intआसपास अनावश्यक कोष्ठकों होने a। यह हमेशा एक घोषणा के रूप में लिया जाता है, इसलिए autoयहां कुछ भी उपयोगी नहीं जोड़ा जाएगा, लेकिन इसके बजाय मानव के लिए होगा। लेकिन फिर, मानव निरर्थक कोष्ठक को दूर करने के लिए बेहतर aहोगा, मैं कहूंगा:

int(a);

autoC ++ 0x के साथ आने के नए अर्थ के साथ, मैं कोड में C ++ 03 के अर्थ के साथ इसका उपयोग करने को हतोत्साहित करूंगा।


4
C ++ कंपाइलर अक्सर फ़ंक्शंस से वापसी मूल्यों के लिए निहितार्थ का उपयोग करते थे, वापस एआरएम दिनों में मानक से पहले ... EMPIRE से पहले ...
डैनियल इयरविकेर

1
मैं सिर्फ इसे अपने संकलक के रूप में पहचानता हूं कि मुझे यह बताने का तरीका है कि मैं एक फ़ंक्शन को अग्रेषित करना भूल गया हूं। यह मुझे बताएगा कि किसी फ़ंक्शन का उपयोग उस तरीके से अलग था, जिसे निहित इंट के कारण घोषित किया गया था।
कार्सन मायर्स

29
सबसे अच्छी बात यह है कि प्रोग्रामर खुद को "इंट" (तीन अक्षर) लिखने से बचाने के लिए "ऑटो" (चार अक्षर) लिखते थे।
मैक्स लाइबबर्ट

30
@ मोम - हे, बहुत से लोग "वर्ल्ड वाइड वेब" के संक्षिप्त नाम के रूप में "डबल-यू-डबल-यू-डबल-यू" कहते हैं।
डैनियल इयरविकर

3
@smichak नहीं, "अस्थिर" एक प्रकार का क्वालीफायर है। यह निर्धारित करने के बजाय कि किसी मान को कहाँ संग्रहीत करना है, यह वाष्पशील योग्य प्रकार की वस्तु से लिखने और पढ़ने के व्यवहार को बदलता है। अस्थिर योग्य स्थिर भंडारण अवधि चर (स्थानीय 'स्थिर' भंडारण वर्ग, गैर-स्थानीय चर) के रूप में अस्वाभाविक योग्य स्टैक चर (ऑटो स्टोरेज क्लास) हो सकते हैं। इसके अलावा, मुझे नहीं पता कि "रजिस्टर वाष्पशील" एक वैध संयोजन है :)
जोहान्स स्काउब -

86

C ++ 11 में, autoनया अर्थ है: यह आपको स्वचालित रूप से एक चर के प्रकार को कम करने की अनुमति देता है।

क्यों यह कभी उपयोगी है? आइए एक मूल उदाहरण पर विचार करें:

std::list<int> a;
// fill in a
for (auto it = a.begin(); it != a.end(); ++it) {
  // Do stuff here
}

autoप्रकार का एक इटरेटर वहाँ पैदा करता है std::list<int>::iterator

यह कुछ गंभीर रूप से जटिल कोड को पढ़ने में बहुत आसान बना सकता है।

एक और उदाहरण:

int x, y;
auto f = [&]{ x += y; };
f();
f();

वहाँ, autoएक चर में लंबोदर अभिव्यक्ति को संग्रहीत करने के लिए आवश्यक प्रकार घटाया गया। विकिपीडिया पर इस विषय पर अच्छा कवरेज है।


4
अभी भी यकीन नहीं है कि यह ऑटो का एक महान उपयोग है। कोड को पढ़ना आसान होना चाहिए, लिखना आसान नहीं!
दनादन

38
मुझे आपके बारे में पता है लेकिन मुझे यह पढ़ने में बहुत आसान लगता है जैसे कि टाइप्टर स्पैम।
ओवर

17
और अगर कुछ रेज़ोन ज़ो के लिए वर्ग को सूची से बदलने का निर्णय लेते हैं <int> कुछ अन्य वर्ग के लिए, तो आपको हर पुनरावृत्त घोषणा की खोज नहीं करनी होगी और इसे बदलना होगा।
रसल

2
@KarateSnowMachine: यदि आप कॉन्स्टेंस चाहते हैं, तो आप "ऑटो" के बजाय "कॉन्स्टैट ऑटो" का उपयोग करेंगे।
डारथ हैप्पीफेस

4
@darth const auto it = a.begin();आपको एक कॉन्स्टेबल देगा iterator, न कि एक const_iterator। आप अभी भी तत्व को बदलते हैं, लेकिन ++itसंकलन करने में विफल होंगे। ए पाने के लिए const_iterator, आप उपयोग करेंगेauto it = a.cbegin();
fredoverflow

35

ऑटो कीवर्ड का फिलहाल कोई उद्देश्य नहीं है। आप बिलकुल सही कह रहे हैं कि यह सिर्फ स्थानीय वैरिएबल के डिफॉल्ट स्टोरेज क्लास को आराम देता है, वास्तव में उपयोगी विकल्प है static

C ++ 0x में इसका बिल्कुल नया अर्थ है। इससे आपको लगता है कि यह कितना बेकार था!


1
अरे यार, क्या यह कभी बेकार है। मुझे नया अर्थ पसंद है। यह कुछ कोड को बहुत कम क्रिया और अनावश्यक बनाता है।
कार्सन मायर्स

हां, C # में समतुल्य का उपयोग करने से शायद बहुत फर्क पड़ेगा। C ++ में अधिक यदि आप अभिव्यक्ति टेम्पलेट का उपयोग कर रहे हैं जहां प्रकार इतने जटिल हैं कि वे कभी भी हाथ से लिखे जाने का इरादा नहीं थे।
डैनियल ईयरविकर

7

autoनेस्टेड कार्यों के लिए जीसीसी का एक विशेष उपयोग है - यहां देखें ।

यदि आपके पास नेस्टेड फ़ंक्शन है जिसे आप इसकी परिभाषा से पहले कॉल करना चाहते हैं, तो आपको इसे घोषित करने की आवश्यकता है auto


यह एक महान, यद्यपि संकलक-निर्भर, ऑटो का कार्यान्वयन है। शोध के लिए धन्यवाद :)
कार्सन मायर्स

3

"ऑटो" माना जाता है कि संकलक को खुद के लिए तय करना है कि चर (मेमोरी या रजिस्टर) कहां रखा जाए। इसका एनालॉग "रजिस्टर" है, जो माना जाता है कि संकलक इसे एक रजिस्टर में रखने की कोशिश करता है। आधुनिक संकलक दोनों को अनदेखा करते हैं, इसलिए आपको भी करना चाहिए।


1
बिल्कुल नहीं - यदि आप इसे "रजिस्टर" के साथ घोषित करते हैं, तो संकलक आपको चर पर ऑपरेटर-ऑपरेटर (और फू) का उपयोग करने की अनुमति नहीं देते हैं, क्योंकि, यह मेमोरी में कहीं भी मौजूद नहीं है (और इस तरह इसका कोई पता नहीं है)।
टिम Timस

3

फ़ंक्शन के लिए महत्वपूर्ण होने पर मैं इस कीवर्ड का स्पष्ट रूप से दस्तावेज़ में उपयोग करता हूं, कि स्टैक-आधारित प्रोसेसर के लिए वेरिएबल को स्टैक पर रखा जाए। फ़ंक्शन से लौटने से पहले स्टैक को संशोधित करते समय (या सर्विस रूटीन को बाधित) करते समय इस फ़ंक्शन की आवश्यकता हो सकती है। इस मामले में मैं घोषणा करता हूं:

auto unsigned int auiStack[1];   //variable must be on stack

और फिर मैं चर के बाहर पहुंचता हूं:

#define OFFSET_TO_RETURN_ADDRESS 8     //depends on compiler operation and current automatics
auiStack[OFFSET_TO_RETURN_ADDRESS] = alternate_return_address;

तो autoकीवर्ड इरादे को दस्तावेज़ करने में मदद करता है।


मुझे लगता है कि यह केवल संकेत देने का इरादा है, क्योंकि कीवर्ड वास्तव में स्टैक प्लेसमेंट को लागू नहीं करता है, अब केवल इसे छोड़ने के बजाय इसे करना होगा।
अंडरस्कोर_ड

2

स्ट्रॉस्ट्रुप के अनुसार, "द सी प्रोग्रामिंग लैंग्वेज" (4 वें संस्करण, सी 11 को कवर करते हुए) में, 'ऑटो' के उपयोग के निम्नलिखित प्रमुख कारण हैं (धारा 2.2.2) (स्ट्रॉस्ट्रुप शब्द उद्धृत हैं):

1)

परिभाषा एक बड़े दायरे में है जहां हम अपने कोड के पाठकों को स्पष्ट रूप से दिखाई देने वाले प्रकार बनाना चाहते हैं।

'ऑटो' और इसके आवश्यक इनिशलाइज़र से हम एक नज़र में वेरिएबल के प्रकार को जान सकते हैं!

2)

हम परिवर्तनशील रेंज या परिशुद्धता के बारे में स्पष्ट होना चाहते हैं (जैसे, फ्लोट के बजाय डबल)

मेरी राय में एक मामला जो यहां फिट बैठता है, वह कुछ इस तरह है:

   double square(double d)
    {
        return d*d; 
    }

    int square(int d)
    {
        return d*d; 
    }

    auto a1 = square(3);

    cout << a1 << endl;

    a1 = square(3.3);

    cout << a1 << endl;

3)

'ऑटो' के उपयोग से हम अतिरेक से बचते हैं और लंबे प्रकार के नाम लिखते हैं।

एक अस्थायी पुनरावृत्त से कुछ लंबे प्रकार के नाम की कल्पना करें:

(खंड 6.3.6.1 से कोड)

template<class T> void f1(vector<T>& arg) {
    for (typename vector<T>::iterator p = arg.begin(); p != arg.end();   p)
        *p = 7;

    for (auto p = arg.begin(); p != arg.end();   p)
        *p = 7;
}

1

पुराने संकलक में, ऑटो एक तरह से स्थानीय चर घोषित करने का एक तरीका था। आप बिना किसी ऑटो कीवर्ड या कुछ ऐसे टर्बो सी जैसे पुराने संकलक में स्थानीय चर घोषित नहीं कर सकते।


1

C ++ 0x में ऑटो कीवर्ड का नया अर्थ Microsoft के Stephan T. Lavavej द्वारा बहुत अच्छी तरह से वर्णन किया गया है जो यहाँ MSDN के चैनल 9 साइट पर पाए गए STL पर एक स्वतंत्र रूप से देखने योग्य / डाउनलोड करने योग्य वीडियो व्याख्यान में है

व्याख्यान अपनी संपूर्णता में देखने लायक है, लेकिन ऑटो कीवर्ड के बारे में हिस्सा 29 वें मिनट के निशान (लगभग) पर है।


0

क्या 'स्थानीय चर' के अलावा 'ऑटो' का कोई और अर्थ है?

C ++ 03 में नहीं।

कुछ भी ऐसा नहीं है जो आपके लिए निहित नहीं है जहाँ भी आप इसका उपयोग करना चाहते हैं?

कुछ भी नहीं, C ++ 03 में।

कैसे एक ऑटो चर कार्यक्रम के दायरे में व्यवहार करता है? फ़ाइल-स्कोप में एक स्थिर ऑटो चर क्या है?

किसी फ़ंक्शन / विधि बॉडी के बाहर कीवर्ड की अनुमति नहीं है।

क्या इस कीवर्ड का कोई उद्देश्य है [C ++ 03 में] पूर्णता के लिए मौजूदा के अलावा अन्य?

हैरानी की बात है, हाँ। C ++ डिजाइन मानदंड में C के साथ पिछड़ी संगतता का एक उच्च स्तर शामिल था। C में यह कीवर्ड था और C ++ में इसके प्रतिबंध या इसके अर्थ को फिर से परिभाषित करने का कोई वास्तविक कारण नहीं था। इसलिए, उद्देश्य सी के साथ एक कम असंगति थी।

क्या इस कीवर्ड का C के अलावा कोई भी उद्देश्य पूर्णता के लिए मौजूद है?

मैंने हाल ही में एक सीखा: बी। से प्राचीन कार्यक्रमों के पोर्टिंग में आसानी, बी नामक एक भाषा से विकसित हुई जिसका वाक्यविन्यास सी के समान था। हालांकि, बी के पास कोई प्रकार नहीं था। बी में चर घोषित करने का एकमात्र तरीका इसका भंडारण प्रकार ( autoया extern) निर्दिष्ट करना था । इस कदर:

ऑटो मैं;

यह सिंटैक्स अभी भी C में काम करता है और इसके बराबर है

int i;

क्योंकि C में, स्टोरेज क्लास डिफॉल्ट करता है auto, और टाइप डिफॉल्ट करता है int। मुझे लगता है कि हर एक कार्यक्रम जो बी में उत्पन्न हुआ था और सी को पोर्ट किया गया था auto, उस समय सचमुच चर से भरा था ।

C ++ 03 अब C शैली को अंतर्निहित करने की अनुमति नहीं देता है, लेकिन इसने नो-लॉन्ग-बिलकुल-उपयोगी autoकीवर्ड को संरक्षित किया है क्योंकि अंतर्निहित int के विपरीत, यह C के सिंटैक्स में कोई परेशानी पैदा करने के लिए नहीं जाना जाता था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.