2010-04-13 25 views
6

मैं कोडिंग करने के लिए नया हूं..और मेरे पास सवाल है कि छात्र क्यों है; ब्रैकेट के बाद .. क्या यह एक प्रारूप है जिसे हमें पालन करना है।सी/सी ++ टाइपपीफ/structs

+1

के साथ पिछड़ा संगतता बनाए रखने के लिए यह सी है, सी ++ नहीं है। क्या आप वाकई सही भाषा का जिक्र कर रहे हैं? –

+5

सी या सी ++, इस उदाहरण में कोई फर्क नहीं पड़ता। Google पर या अपनी पुस्तकों में टाइपपीफ देखें। –

+6

@gbrandt: हां, लेकिन सी ++ में इस तरह की संरचना घोषित करने का कोई कारण नहीं है। –

उत्तर

0

छात्र टाइप किए गए नए प्रकार का नाम है। StudentRec परिभाषित संरचना का नाम है।

13

यह संरचना का मतलब करने के लिए एक टाइपनाम "छात्र" बना रहा है। इस उद्देश्य के लिए typedef का उपयोग करना C++ में अनावश्यक है। इसे इस तरह परिभाषित किया जा सकता है:

struct Student { 
    char lastname[NAMELEN]; 
    char firstname[NAMELEN]; 
    long int ID; 
    int finalmark; 
}; 
+1

ज्यादातर मामलों में यह अनावश्यक है, लेकिन संरचना की परिभाषा और टाइपिंग के बीच थोड़ा अंतर है। पहचानकर्ता अलग-अलग नामस्थानों में रहते हैं (सी ++ में 'नेमस्पेस' कीवर्ड के अर्थ में नहीं)। http://stackoverflow.com/questions/1675351/typedef-struct-vs-struct-definitions/1675446#1675446 –

17

आप दो चीजों को भ्रमित कर रहे हैं। सी में आप इस तरह की एक struct को परिभाषित कर सकते हैं:

struct foo { 
    int a, b; 
}; 

फिर से एक का उपयोग करने के लिए आप यह करने के लिए है:

struct foo myFoo; 

यह वास्तव में अधिक शब्दों वाले है, तो वे typedef का उपयोग कर बनाने के लिए की इस शानदार विचार था एक नया प्रकार मैं कुछ इस तरह कर सकते हैं:

typedef int myInt; 

और फिर इसे का उपयोग करें:

myInt x; 

तो क्या आप कर रहे हैं की घोषणा कर रहा है एक नए प्रकार है कि वहाँ, छात्र, जो एक struct के बराबर है StudentRec । परंपरा के मुताबिक, कई लोगों को struct के लिए के रूप में typedef के लिए एक ही नाम का उपयोग करें - यह कानूनी है:

typedef struct foo { int a, b; } foo; 
0

इस में से कोई भी C++ पर लागू होता है। C++ में पसंद करते हैं:

struct Foo 
{ 
    . . . 
}; 

बाकी केवल C पर लागू होता है।

तकनीकी रूप से struct Foo {}; अधिकांश उद्देश्यों के लिए पर्याप्त है। हालांकि यह struct के रूप में उपयोग करने के लिए थोड़ा सा वर्बोज़ है जब प्रत्येक बार प्रकार का उपयोग किया जाता है।

struct Foo {} 

void func(struct Foo* foo); 

एक टाइपपीफ यह आसान बनाता है।

typedef struct Foo { } Foo; 
void func(Foo* foo); 

एक एक लाइनर कर जब यह भी इस वाक्य विन्यास का उपयोग करने के लिए संभव है:

typedef struct { } Foo; 
void func(Foo* foo); 

ऐसा अनाम struct पैदा कर रही है और उसके बाद देने

struct Foo { }; 
typedef struct Foo Foo; 
void func(Foo* foo); 

यह आगे के साथ छोटा किया जा सकता यह नाम फू है। आप इसे अक्सर enum एस के साथ देखते हैं।

typedef enum { } Bar; 

एक कारण है कि इंटियल रिडंडेंट फू आमतौर पर वहां छोड़ा जाता है। एक लिंक्ड सूची की तरह एक स्वयं संदर्भ संरचना बनाने का यह एकमात्र तरीका है।

typedef struct Node 
{ 
    Node* next; 
} Node; 

प्रारंभिक Node जहां struct करने के लिए एक सूचक की घोषणा करने का कोई तरीका नहीं होगा ommited हैं। तकनीकी रूप से यह भी वैध है, लेकिन अब आपको केवल एक के बजाय 2 नामों के साथ आना होगा।

typedef struct node_ 
{ 
    node_* next; 
} Node; 

तो क्यों उपयोग:

typedef struct Foo { } Foo; 

एकरूपता के लिए। यह घोषणा शैली आपके सभी आधारों को कवर करती है, इसलिए संरचना को घोषित करते समय आपको इसके बारे में कभी सोचना नहीं पड़ता है।

4

सी में संरचना नामों और प्रकार के नामों (जैसे int) के लिए अलग-अलग नामस्थान हैं {प्रकार नामस्थान को चर और फ़ंक्शन नेमस्पेस के साथ साझा किया जाता है, इसलिए उस से अवगत रहें}। जब आप एक नई संरचना को परिभाषित करते हैं तो आप स्वचालित रूप से अपना नाम स्ट्रक्चर नेमस्पेस में जोड़ते हैं, लेकिन जब आप उस प्रकार के चर को घोषित करते हैं तो आपको struct के साथ अपना नाम आगे बढ़ाना होगा ताकि संकलक यह देखने के लिए स्ट्रक्चर नेमस्पेस को देखना चाहें कि यह वास्तव में क्या है कि आप यह चर होना चाहते हैं।

टाइप किए गए कीवर्ड का उपयोग करके आप चर के लिए नाम नाम टाइप कर सकते हैं ताकि आपको अपनी घोषणाओं में संरचना कीवर्ड का उपयोग न करना पड़े।

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

इस के अन्य वैधानिक स्वरूप उदाहरण के लिए सी में हैं:

/* This declares a variable foo whose type has no name but is a struct that contains one int named x */ 
struct { 
    int x; 
} foo; 

/* This adds bar to the type namespace without adding an entry to the struct namespace. */ 
typedef struct { 
    int y; 
} bar; 

/* This adds the name baz to the struct namespace and declares a variable named b of this type */ 
struct baz { 
    int z; 
} b; 

/* This adds the name ralf to the type namespace which also refers to this type */ 
typedef struct baz ralf; 

सी ++ अलग नाम स्थान संरचना, जो मुझे यकीन है कि आपने गौर किया है क्योंकि यह नाम स्थान कीवर्ड हूँ है। इस उदाहरण में हालांकि सी ++ सी से अधिक सरल है। एक स्ट्रक्चर (या क्लास या यूनियन या एनम) को परिभाषित करना स्वचालित रूप से उस नाम को जोड़ता है जिसे आपने टाइपस्पेस नाम दिया है, जो टाइपस्फी नाम जोड़ता है। यह अधिकांश भाग के लिए चीजों को बहुत सरल बनाता है, लेकिन कुछ गठिया हैं। इन्हें ज्यादातर सी के साथ पिछड़े संगतता को बनाए रखने के साथ करना होता है। अधिकांशतः इस संगतता को typedefs struct foo foo; पर ध्यान देने के साथ करना पड़ता है और इसे पहले से उपयोग किए गए नाम से कुछ नाम देने की कोशिश करने की त्रुटि के रूप में नहीं माना जाता है।

एक और मुद्दा यह काफी आम सी कोड के इस प्रकार के साथ आता है:

struct shoe { 
    int size; 
} shoe; 

यह सी में आम है विशेष रूप से जब एक struct का केवल एक की जरूरत का अस्तित्व। सी में यह आसान होगा क्योंकि struct shoe और परिवर्तनीय shoe के नामों के बीच कोई टक्कर नहीं होगी। सी ++ में यह अभी भी काम करता है हालांकि सी

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