2015-02-16 3 views
5

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

f(int a,int b) 
{ 
    int a; 
    a=20; 
    return a; 
} 

यह a की पुन: घोषणा त्रुटि क्यों देता है? यहाँ a सही परिभाषित किया गया है -

  • f(int a,int b): इसके बारे में a क्योंकि में एक से अधिक परिभाषा देना नहीं करना चाहिए?
  • और फ़ंक्शन बॉडी में, int a फिर से परिभाषित किया गया है?

तो एकाधिक परिभाषा त्रुटि क्यों नहीं?

+6

परिभाषाएं भी घोषणाएं हैं। एकाधिक घोषणाओं की जांच कई परिभाषाओं के लिए जांचने से पहले निदान की जाती है –

+0

पैरामीटर सूची 'f (int a ...)' घोषित करती है, फिर आप शरीर में 'int a' घोषित करते हैं - पुनर्विक्रय ... –

+2

@ डेविडसी। रैंकिन I लगता है कि वह पूछ रहा है कि क्यों त्रुटि संदेश "एकाधिक परिभाषा" के बजाय "पुन: घोषणा" कहता है –

उत्तर

5

एक परिभाषा हमेशा एक घोषणा है। अंतर यह है कि एक परिभाषा जो भी आप कुछ मूल्य घोषित करती है उसे भी देती है।

f(int a, /* Defines a */ 
int b) 
{ 
    int a; /* Declares a - error! */ 
    a=20; /* initializes a */ 
    return a; 
} 

आप शायद ऐसा करने का मतलब:

अपने उदाहरण में, वैसे, यह केवल एक पुन: घोषणा त्रुटि है

f(int a, /* Defines a */ 
int b) 
{ 
    int a = 20; /* Declares and defines a - error! */ 
    return a; 
} 

लेकिन इस मामले में, सबसे compilers होगा एक "redeclaration" त्रुटि भी फेंक दें।

Error: 'a' redeclared as a different kind of symbol

है ऐसा इसलिए है क्योंकि a मूल रूप से एक पैरामीटर है, जो समारोह की गुंजाइश के अंदर एक चर परिभाषा से अलग है के रूप में परिभाषित किया गया है: उदाहरण के लिए, जीसीसी निम्न त्रुटि फेंकता है। चूंकि संकलक देखता है कि आप को फिर से घोषित कर रहे हैं जो आपकी नई घोषणा की तुलना में एक अलग "नस्ल" है, यदि आपकी अवैध घोषणा एक परिभाषा है या नहीं, तो इससे कम परवाह नहीं किया जा सकता है, क्योंकि यह "परिभाषा" को अलग-अलग मानता है फ़ंक्शन पैरामीटर और फ़ंक्शन स्थानीय चर के संदर्भ में।

हालांकि, अगर आप ऐसा करते हैं:

int c = 20; 
int c = 20; 

जीसीसी, उदाहरण के लिए, एक परिभाषा त्रुटि फेंकता है, क्योंकि दोनों c -s समारोह के स्थानीय चर रहे हैं।

+2

वैसे मुझे आपका जवाब पसंद है, अगर मैं गलत हूं, तो मुझे यह समझने में मदद मिली है, तो आप कह रहे हैं कि फ़ंक्शन के पैरामीटर की घोषणा स्थानीय चर की घोषणा से अलग है, इसलिए हमें इस त्रुटि को इस तरह मिलता है मामला बाहरी int एक; और बाहरी चार ए; विभिन्न प्रकार के घोषणा –

+0

@ रोहितसालुजा: फ़ंक्शन का पैरामीटर * हमेशा * एक परिभाषा है। इसे फ़ंक्शन हेडर में घोषित किया गया है और कुछ तर्कों के साथ फ़ंक्शन को कॉल करके प्रारंभ किया गया है, यानी जब फ़ंक्शन निष्पादित किया जाता है, तो सभी पैरामीटर प्रारंभ किए जाएंगे, इसलिए उन्हें * परिभाषित * किया जाएगा। जब आप किसी फ़ंक्शन के अंदर पैरामीटर को फिर से परिभाषित करने का प्रयास करते हैं, तो यह * आपके जैसे उदाहरण में एक confilcting-type त्रुटि के समान * है, लेकिन इस मामले में, ऐसा इसलिए है क्योंकि पैरामीटर और स्थानीय चर * विभिन्न प्रकार हैं प्रतीकों * में वे एक अलग फैशन में परिभाषित हैं। – Mints97

+0

आप प्रारंभिकरण की परिभाषा से संबंधित क्यों हैं, मुझे लगता है कि वे दोनों अलग-अलग चीजें हैं, प्रारंभिकता केवल कुछ मूल्य के साथ चर प्रदान कर रही है, उससे अधिक कुछ नहीं:/ –

1

जब आप अपने कोड में एक चर घोषित करते हैं, तो आपकी घोषणा में उपयोग किए गए डेटा प्रकार के आधार पर स्मृति का एक ब्लॉक उस चर नाम से आवंटित किया जाएगा।

लेकिन जब आप एक ही चर को फिर से चलाने की कोशिश करते हैं तो प्रोसेसर स्मृति को आवंटित करने का प्रयास करता है जो पहले से ही उसी नाम से आवंटित किया जाता है।इतनी के रूप में प्रोसेसर चेहरा अस्पष्टता कि चर नाम संकलक के साथ स्मृति ब्लॉक का उपयोग करने की कोशिश करते हुए अनुमति नहीं देते कि शिक्षा, इसलिए कई घोषणाओं अनुमति नहीं दी जाएगी और आप जीसीसी संकलक कह में एक त्रुटि प्राप्त होगी,

line 3 col 10 [Error]redeclaration of 'int a' 
line 1 col 7  [Error]'int a' previously declared here 

स्मृति लेआउट पर अपने कोड

f(int a,int b) //first declaration of 'a' 
    { 
     int a;  //redeclaration of 'a', whose memory is already allocated 
     a=20; 
     return a; 
    } 

में दो ब्लॉकों एक ही identit नहीं हो सकता वाई (परिवर्तनीय नाम), इसलिए संकलक एक पुनर्विक्रय त्रुटि फेंकता है क्योंकि एकाधिक घोषणाएं संभव नहीं होती हैं, जब चर 'ए' को फिर से घोषित किया जाता है।

+1

मुझे लगता है कि आप घोषणा और परिभाषा के बीच उलझन में हैं। यह परिभाषा है जो स्मृति को आवंटित नहीं करती है। घोषणा और परिभाषा के बारे में अधिक जानकारी के लिए इस [लिंक] (http://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration) का पालन करता है। –

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