मुझे नहीं लगता कि मैं मौलिक रूप से समझता हूं कि क्या enum
है, और इसका उपयोग कब करना है।
उदाहरण के लिए:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
यहाँ वास्तव में क्या घोषित किया जा रहा है?
मुझे नहीं लगता कि मैं मौलिक रूप से समझता हूं कि क्या enum
है, और इसका उपयोग कब करना है।
उदाहरण के लिए:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
यहाँ वास्तव में क्या घोषित किया जा रहा है?
जवाबों:
तीन बातें यहाँ घोषित किया जा रहा है: एक गुमनाम enumerated प्रकार घोषित किया जाता है, ShapeType
अनाम गणन के लिए एक typedef घोषित किया जा रहा है, और तीन नामों kCircle
, kRectangle
और kOblateSpheroid
अभिन्न स्थिरांक के रूप में घोषित किया जा रहा है।
चलो कि नीचे तोड़ो। सबसे सरल मामले में, एक गणना के रूप में घोषित किया जा सकता है
enum tagname { ... };
यह टैग के साथ एक गणना की घोषणा करता है tagname
। C और ऑब्जेक्टिव-सी (लेकिन C ++ नहीं ) में, इस से संबंधित किसी भी संदर्भ को कीवर्ड से पहले होना चाहिए enum
। उदाहरण के लिए:
enum tagname x; // declare x of type 'enum tagname'
tagname x; // ERROR in C/Objective-C, OK in C++
enum
हर जगह कीवर्ड का उपयोग करने से बचने के लिए , एक टाइप-बी बनाया जा सकता है:
enum tagname { ... };
typedef enum tagname tagname; // declare 'tagname' as a typedef for 'enum tagname'
इसे एक पंक्ति में सरल बनाया जा सकता है:
typedef enum tagname { ... } tagname; // declare both 'enum tagname' and 'tagname'
और अंत में, अगर हमें कीवर्ड के enum tagname
साथ उपयोग करने में सक्षम होने की आवश्यकता नहीं है, तो हम अनाम enum
बना सकते हैं enum
और केवल इसे टाइपराइंड के साथ घोषित कर सकते हैं :
typedef enum { ... } tagname;
अब, इस मामले में, हम ShapeType
एक गुमनाम संस्मरण का टाइपडिफेड नाम घोषित कर रहे हैं । ShapeType
वास्तव में सिर्फ एक अभिन्न प्रकार है, और केवल चर जो घोषणा में सूचीबद्ध मानों में से एक (है कि, में से एक पकड़ घोषित करने के लिए इस्तेमाल किया जाना चाहिए kCircle
, kRectangle
और kOblateSpheroid
)। आप एक ShapeType
वैरिएबल को किसी अन्य मान को कास्टिंग द्वारा असाइन कर सकते हैं , हालांकि, एनम मूल्यों को पढ़ते समय आपको सावधान रहना होगा।
अंत में, kCircle
, kRectangle
, और kOblateSpheroid
ग्लोबल नेम स्पेस में अभिन्न स्थिरांक के रूप में घोषित कर रहे हैं। चूंकि कोई विशिष्ट मान निर्दिष्ट नहीं किया गया था, वे 0 से शुरू होने वाले लगातार पूर्णांक को असाइन किए जाते हैं, इसलिए kCircle
0 है, kRectangle
1 है, और kOblateSpheroid
2 है।
Apple Xcode 4.4 के बाद से इस तरह से परिभाषित करने की सिफारिश करता है :
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
वे एक आसान मैक्रो प्रदान करते हैं NS_ENUM
:
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
ये परिभाषाएँ मजबूत प्रकार की जाँच और बेहतर कोड पूर्ति प्रदान करती हैं। मुझे इसका आधिकारिक दस्तावेज नहीं मिला NS_ENUM
, लेकिन आप WWDC 2012 के सत्र से "आधुनिक उद्देश्य-सी" वीडियो देख सकते हैं ।
अपडेट करें
यहाँ
आधिकारिक दस्तावेज के लिए लिंक ।
NS_ENUM
गई है, NSHipster द्वारा Apple के मैक्रो की व्याख्या देखें : NSHipster.com/ns_enum-ns_options
एक उपयोगकर्ता परिभाषित प्रकार के संभावित मान है kCircle
, kRectangle
या kOblateSpheroid
। एनम (kCircle, आदि) के अंदर के मान हालांकि, एनम के बाहर दिखाई देते हैं। यह ध्यान में रखना महत्वपूर्ण है ( int i = kCircle;
उदाहरण के लिए मान्य है)।
64-बिट परिवर्तन के लिए अद्यतन: 64-बिट परिवर्तनों के बारे में सेब डॉक्स के अनुसार ,
एनुमरेशन भी टाइप किए जाते हैं: एलएलवीएम कंपाइलर में एन्यूमरेटेड प्रकार एन्यूमरेशन के आकार को परिभाषित कर सकते हैं। इसका मतलब यह है कि कुछ प्रगणित प्रकारों का आकार भी हो सकता है जो आपकी अपेक्षा से बड़ा हो। समाधान, अन्य सभी मामलों में, डेटा प्रकार के आकार के बारे में कोई धारणा नहीं बनाना है। इसके बजाय, उचित डेटा प्रकार के साथ किसी भी गणना किए गए मान को एक चर पर असाइन करें
तो अगर आप के लिए है प्रकार के साथ enum बनाने यदि आप 64-बिट के लिए समर्थन वाक्य रचना नीचे के रूप में।
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
या
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
अन्यथा, यह चेतावनी के रूप में ले जाएगा Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType
स्विफ्ट-प्रोग्रामिंग के लिए अपडेट:
स्विफ्ट में, एक सिंटैक्स परिवर्तन है।
enum ControlButtonID: NSUInteger {
case kCircle , kRectangle, kOblateSpheroid
}
एनम (एन्यूमरेशन का संक्षिप्त नाम) का उपयोग मानों (एन्यूमिटर) के एक सेट को एन्यूमरेट करने के लिए किया जाता है। एक मान एक प्रतीक (एक शब्द) द्वारा दर्शाई गई एक अमूर्त चीज है। उदाहरण के लिए, एक बुनियादी दुश्मनी हो सकती है
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };
इस एनम को अनाम कहा जाता है क्योंकि आपके पास इसे नाम देने के लिए कोई प्रतीक नहीं है। लेकिन यह अभी भी पूरी तरह से सही है। बस इसे ऐसे ही इस्तेमाल करें
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
ठीक है। जीवन सुंदर है और सब कुछ अच्छा हो जाता है। लेकिन एक दिन आपको myGrandFatherPantSize को स्टोर करने के लिए एक नए वेरिएबल को परिभाषित करने के लिए इस एनम को फिर से उपयोग करने की आवश्यकता है, फिर आप इसे देखें:
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;
लेकिन फिर आपके पास एक संकलक त्रुटि है "एन्यूमरेटर का पुनर्वित्त"। दरअसल, समस्या यह है कि कंपाइलर को यह सुनिश्चित नहीं है कि आप पहले एनम और आप दूसरे हैं एक ही बात का वर्णन करते हैं।
फिर अगर आप कई जगहों पर एनुमरेटर्स (यहां xs ... xxxxl) के एक ही सेट को फिर से उपयोग करना चाहते हैं, तो आपको इसे एक अद्वितीय नाम के साथ टैग करना होगा। दूसरी बार जब आप इस सेट का उपयोग करेंगे तो आपको केवल टैग का उपयोग करना होगा। लेकिन यह मत भूलिए कि यह टैग एनम शब्द को प्रतिस्थापित नहीं करता है, बल्कि एन्यूमेरेटर्स के सेट को बदल देता है। फिर ध्यान रखें कि हमेशा की तरह एनम का उपयोग करें। ऐशे ही:
// Here the first use of my enum
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
// here the second use of my enum. It works now!
enum sizes myGrandFatherPantSize;
आप इसे एक पैरामीटर परिभाषा में भी उपयोग कर सकते हैं:
// Observe that here, I still use the enum
- (void) buyANewDressToMyGrandMother:(enum sizes)theSize;
आप कह सकते हैं कि हर जगह की गणना लिखना सुविधाजनक नहीं है और कोड थोड़ा अजीब लगता है। तुम सही हो। एक वास्तविक प्रकार बेहतर होगा।
यह शिखर सम्मेलन के लिए हमारी महान प्रगति का अंतिम चरण है। केवल एक टाइपफ़ेड जोड़कर हम अपने एनम को एक वास्तविक प्रकार में बदल देते हैं। अरे आखिरी बात, आपकी कक्षा के भीतर टाइप्डफ की अनुमति नहीं है। फिर ऊपर अपने प्रकार को परिभाषित करें। इसको ऐसे करो:
// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type
@interface myClass {
...
size_type myGrandMotherDressSize, myGrandFatherPantSize;
...
}
याद रखें कि टैग वैकल्पिक है। फिर यहाँ से, उस स्थिति में, हम एन्यूमरेटर्स को टैग नहीं करते हैं, बल्कि एक नए प्रकार को परिभाषित करते हैं। तब हमें वास्तव में इसकी कोई आवश्यकता नहीं है।
// enum definition
typedef enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } size_type;
@interface myClass : NSObject {
...
size_type myGrandMotherDressSize, myGrandFatherPantSize;
...
}
@end
यदि आप XCode के साथ Objective-C में विकसित कर रहे हैं तो मैं आपको NS_ENUM के साथ उपसर्गित कुछ अच्छे मैक्रोज़ की खोज करने देता हूँ। आपको अच्छे एनमों को आसानी से परिभाषित करने में मदद करनी चाहिए और संकलन करने से पहले स्थैतिक विश्लेषक को आपके लिए कुछ दिलचस्प जांच करने में मदद मिलेगी।
अच्छा एनम!
typedef
मौजूदा चर प्रकार के नाम को फिर से परिभाषित करने के लिए उपयोगी है। यह डेटाटाइप को कॉल करने का छोटा और सार्थक तरीका प्रदान करता है। उदाहरण के लिए:
typedef unsigned long int TWOWORDS;
यहाँ, टाइप किए गए लंबे int को TWOWORDS के प्रकार से पुनर्परिभाषित किया जाता है। इस प्रकार, अब हम लिखित रूप से लंबे समय तक अप्रयुक्त प्रकार के चर घोषित कर सकते हैं,
TWOWORDS var1, var2;
के बजाय
unsigned long int var1, var2;
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
तो आप इसे उपयोग कर सकते हैं जैसे: -
ShapeType shape;
तथा
enum {
kCircle,
kRectangle,
kOblateSpheroid
}
ShapeType;
अब आप इसका उपयोग कर सकते हैं जैसे: -
enum ShapeType shape;
enum का उपयोग enum तत्वों को मान प्रदान करने के लिए किया जाता है जो संरचना में नहीं किया जा सकता है। इसलिए हर बार पूरा वैरिएबल एक्सेस करने के बजाय हम वैसा ही कर सकते हैं जैसा कि हम एनम में वेरिएबल्स को देते हैं। डिफ़ॉल्ट रूप से यह 0 असाइनमेंट के साथ शुरू होता है, लेकिन हम इसे किसी भी मान को असाइन कर सकते हैं और एनम में अगले वेरिएबल को पिछले मान +1 का मान दिया जाएगा।
आप नीचे प्रारूप में उपयोग कर सकते हैं, रॉ डिफ़ॉल्ट मान 0 से शुरू हो रहा है, इसलिए
आप अपना विशिष्ट आरंभिक मूल्य निर्दिष्ट कर सकते हैं।
typedef enum : NSUInteger {
kCircle, // for your value; kCircle = 5, ...
kRectangle,
kOblateSpheroid
} ShapeType;
ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0
एक टाइपराइफ़ प्रोग्रामर को एक ऑब्जेक्ट-सी प्रकार को दूसरे के रूप में परिभाषित करने की अनुमति देता है। उदाहरण के लिए,
typedef int काउंटर; प्रकार को परिभाषित करता है काउंटर इंट के प्रकार के बराबर है। यह काफी कोड पठनीयता में सुधार करता है।
टंकण सी और सी ++ में एक कीवर्ड है। इसका उपयोग बुनियादी डेटा प्रकारों (चार, इंट, फ्लोट, डबल, स्ट्रक्चर और एनम) के लिए नए नाम बनाने के लिए किया जाता है ।
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
यहां यह एन्यूमरेटेड डेटा टाइप शेप टाइप बनाता है और हम एनम टाइप शेप टाइप के लिए नए नाम लिख सकते हैं जैसा कि नीचे दिया गया है
ShapeType shape1;
ShapeType shape2;
ShapeType shape3;
enum कई प्रकार की "त्रुटियों" को कम कर सकता है और कोड को अधिक प्रबंधनीय बना सकता है
#define STATE_GOOD 0
#define STATE_BAD 1
#define STATE_OTHER 2
int STATE = STATE_OTHER
परिभाषा में कोई अड़चन नहीं है। यह केवल एक प्रतिस्थापन है। यह राज्य की सभी स्थितियों को सीमित करने में सक्षम नहीं है। जब स्टेट 5 को सौंपा जाता है, तो प्रोग्राम गलत होगा, क्योंकि कोई मिलान स्थिति नहीं है। लेकिन संकलक STATE = 5 को चेतावनी देने वाला नहीं है
इसलिए इस तरह का उपयोग करना बेहतर है
typedef enum SampleState {
SampleStateGood = 0,
SampleStateBad,
SampleStateOther
} SampleState;
SampleState state = SampleStateGood;