2009-02-05 23 views
5

मैं ++ आप आसानी से लिख सकते हैंमुझे टाइपिफ़ की आवश्यकता क्यों नहीं है?

enum eEnum { c1, c2 }; 
struct MyStruct { int i; double d; }; 

यह सच है पढ़ने

typedef enum eEnum { c1, c2 } tagEnum; 

typedef struct { int i; double d; } tagMyStruct; 

मैं अफवाहें सुनी है कि इन निर्माणों सी से तारीख सी में कुछ कोड का सामना करना पड़ा? आपको पहले संस्करण की आवश्यकता कब होती है?

उत्तर

10

पहला, दोनों घोषणाएं सी और सी ++ दोनों में कानूनी हैं। हालांकि, सी में, उनके पास थोड़ा अलग अर्थशास्त्र है। (विशेष रूप से, जिस तरह से आप बाद में संरचना का संदर्भ लेते हैं)।

समझने की मुख्य अवधारणा यह है कि सी में, structs एक अलग नामस्थान में मौजूद हैं। सभी अंतर्निहित प्रकार, साथ ही typedefs "डिफ़ॉल्ट" नामस्थान में मौजूद हैं। यही है, जब मैं int टाइप करता हूं, तो कंपाइलर केवल यह "डिफ़ॉल्ट" नामस्थान जांचता है। यदि मैं आपके उदाहरण में "tagMyStruct" टाइप करता हूं, तो संकलक भी केवल एक नामस्थान जांचता है। लेकिन आप किस प्रकार की घोषणा का उपयोग करते हैं, इस आधार पर संरचना उस नामस्थान में मौजूद नहीं हो सकती है।

स्ट्रक्चर अलग हैं, और एक अलग नामस्थान में मौजूद हैं। तो अगर मैं निम्नलिखित घोषणा करते हैं:

struct mystruct {}; 

मैं नहीं आसानी से उस पर mystruct के रूप में देख सकते हैं।

void foo(struct mystruct bar); // Declare a function which takes a mystruct as its parameter 

कौन सा थोड़ा वर्बोज़ और लंबे समय में अजीब हो जाता है: इसके बजाय, मुझे लगता है कि मैं mystruct जो struct नाम स्थान में मौजूद चाहते हैं निर्दिष्ट करना होगा।

typedef struct mystruct mystruct; // From now on, 'mystruct' in the normal namespace is an alias for 'mystruct' in the struct namespace 

और अब, मेरे समारोह सरल तरीके से घोषित किया जा सकता:

void foo(mystruct bar); 

तो आपका पहला उदाहरण बस इन दो चरणों एक साथ विलीन हो जाती है: इसके बजाय, आप यह डिफ़ॉल्ट नाम स्थान में typedef कर सकते हैं घोषित एक संरचना, और एक उपनाम नियमित नामस्थान में डाल दिया। और निश्चित रूप से, चूंकि हम इसे टाइप कर रहे हैं, हमें "मूल" नाम की आवश्यकता नहीं है, इसलिए हम संरचना को अज्ञात बना सकते हैं। तो अपने घोषणा

typedef struct { int i; double d; } tagMyStruct; 

के बाद हम कोई नाम नहीं, जो कि डिफ़ॉल्ट नाम स्थान में 'tagMyStruct' के लिए typedef'ed कर दिया गया है के साथ एक struct है।

इस तरह सी इसका इलाज करता है। दोनों प्रकार की घोषणाएं वैध हैं, लेकिन कोई "डिफ़ॉल्ट" नेमस्पेस में उपनाम नहीं बनाता है, इसलिए जब भी आप टाइप को संदर्भित करते हैं तो आपको स्ट्रक्चर कीवर्ड का उपयोग करना होगा।

सी ++ में, अलग-अलग संरचना नामस्थान मौजूद नहीं है, इसलिए उनका मतलब एक ही बात है। (लेकिन छोटे संस्करण को प्राथमिकता दी जाती है)।

संपादित करें बस स्पष्ट होने के लिए, नहीं, सी में नामस्थान नहीं हैं। सामान्य ज्ञान में नहीं। सी बस पहचानकर्ताओं को दो पूर्वनिर्धारित नामस्थानों में से एक में रखता है। Structs (और enums, जैसा कि मुझे याद है) के नाम एक में रखा गया है, और अन्य सभी पहचानकर्ता दूसरे में हैं। तकनीकी रूप से, ये नामस्थान हैं क्योंकि वे अलग-अलग "कंटेनर" हैं जिनमें नाम विवादों से बचने के लिए रखा गया है, लेकिन वे निश्चित रूप से C++/C# भावना में नामस्थान नहीं हैं।

+0

अच्छा स्पष्टीकरण – Eclipse

+0

तो सी _does_ नामस्थान हैं! :) धन्यवाद, यह कई चीजों को स्पष्ट करता है। – xtofl

+0

xtofl: नहीं, वास्तव में नहीं। सी ++ भावना में नहीं। structs और अंतर्निर्मित प्रकार अलग नामस्थानों में मौजूद हैं, लेकिन उससे परे, नहीं। आप नए नामस्थान, या किसी और चीज की घोषणा नहीं कर सकते हैं। तो यह एक विशेष मामला है। इसके बारे में सोचने का शायद एक बुरा विचार है कि "सी के नामस्थान हैं";) – jalf

1

यह सिर्फ शॉर्टेंड है।

दूसरा उदाहरण में, struct तुम क्या चाहते हैं घोषित करने के लिए इतनी के साथ:

tagMyStruct a; 
+0

यह सी में भी कम है? या आप केवल सी ++ का उल्लेख करते हैं? – xtofl

0

दूसरा संस्करण भी:

struct MyStruct a; 

पहले संस्करण का में, आप इतना के साथ क्या होता है सी में मौजूद है

आप पहले संस्करण का उपयोग करें जब भी आप अपने प्रकार, जैसे नाम हैं:

tagEnum myFunc(tagMyStruct * myArg); 
0

पहला + सी ++ में असुविधाजनक हो सकता है, क्योंकि आप इसे हेडर फ़ाइल में घोषित नहीं कर सकते हैं।

10

सी में, यदि आप

struct MyStruct { int i; double d; }; 

लिखने के थे जब भी आप उस प्रकार को संदर्भित करना चाहता था, आप निर्दिष्ट करने के लिए है कि आप एक struct के बारे में बात कर रहे थे होगा:

struct MyStruct instanceOfMyStruct; 
struct MyStruct *ptrToMyStruct; 
साथ

typedef संस्करण:

typedef struct { int i; double d; } tagMyStruct; 

आप केवल लिखने के लिए है:

+०१२३५१६४१०६
tagMyStruct instanceOfMyStruct; 
tagMyStruct *ptrToMyStruct; 

typedef'd संस्करण के साथ अन्य बड़ा लाभ यह है कि आप ++ दोनों सी और सी में एक ही तरह से struct का उल्लेख कर सकते हैं, जबकि दूसरे संस्करण में वे सी में से C++ में लिए अलग तरह से संदर्भित कर रहे हैं।

+0

"केवल" लिखना होगा "संस्करण" टैगमस्ट्रक्चर ... "आईएसओ" मायस्ट्रक्चर "होगा? या यह सही है? (यह counterintuitive है ...) – xtofl

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