C में एनुमरेटेड टाइप (enum) को कैसे परिभाषित करें?


272

मुझे यकीन नहीं है कि सी एनम का उपयोग करने के लिए उचित वाक्यविन्यास क्या है। मेरे पास निम्नलिखित कोड हैं:

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;

लेकिन यह संकलित नहीं है, निम्न त्रुटि के साथ:

error: conflicting types for strategy
error: previous declaration of strategy was here

मैं क्या गलत कर रहा हूं?


7
वर्षों पुराना सवाल, शायद किसी ने यह नहीं देखा होगा; लेकिन यह एक त्रुटि क्यों है? यह पूरी तरह से अच्छी तरह से काम करना चाहिए क्योंकि यह प्रश्न में है जहाँ तक मेरा ज्ञान जाता है।
उत्तान गीजर

2
@Solver यह वाक्य रचना गलत क्यों है?
एमसीजी

6
@MCQ, नेक्रोड नेक्र्रो को परिगलित कर रहा है: प्रश्न में प्रस्तुत वाक्यविन्यास सी में गलत नहीं है। यह strategyएक गुमनाम गणना प्रकार के रूप में घोषित करता है, और उस प्रकार के घोषित मूल्यों में से एक को असाइन करता है। इसके अलावा, अगर मैं किसी अन्य तुच्छ main()कार्य में प्रस्तुत कोड को लपेटता हूं तो यह मेरे लिए ठीक है, बिना किसी चेतावनी के, 4.4.7 के साथ। कुछ उत्तर समान हैं, इतने शब्दों में नहीं।
जॉन बोलिंगर

5
अधिकांश उत्तर इस तथ्य को याद कर रहे हैं कि प्रश्न में कोड की दो लाइनें केवल एक स्निपेट नहीं हैं। वे संपूर्ण स्रोत फ़ाइल हैं। यदि उन दो पंक्तियों को किसी फ़ंक्शन के शरीर में शामिल किया गया है, तो कोई त्रुटि नहीं है। यदि वे किसी भी फ़ंक्शन घोषणा के बाहर फ़ाइल स्कोप में दिखाई देते हैं, तो आपको उन त्रुटियों के बारे में पता चलेगा, जिनके बारे में ओपी ने पूछा था (साथ ही कुछ अन्य लोगों ने जब मैंने यह कोशिश की थी)। मूलभूत समस्या यह है कि संकलक strategy = IMMEDIATE;एक घोषणा के रूप में इलाज करने की कोशिश कर रहा है । इसका एक रूप है जो पूर्व-एएनएसआई सी में कानूनी होगा, लेकिन आधुनिक सी में यह अवैध है। फ़ाइल दायरे में असाइनमेंट की अनुमति नहीं है।
कीथ थॉम्पसन

3
@ शोवर: enum strategy { ... };नामांकित एक नामांकित प्रकार को परिभाषित करता है enum strategy, जहां strategyटैग है। enum { ... } strategy;एक गुमनाम एन्यूमरेटेड प्रकार (कोई टैग नहीं) और उस प्रकार के एकल ऑब्जेक्ट को नाम देता है strategy। दोनों पूरी तरह से कानूनी हैं; उन्हें सिर्फ अलग चीजों से मतलब है।
कीथ थॉम्पसन

जवाबों:


377

एनम चर घोषित करना इस तरह किया जाता है:

enum strategy {RANDOM, IMMEDIATE, SEARCH};
enum strategy my_strategy = IMMEDIATE;

हालाँकि, आप typedefचर घोषणाओं को छोटा करने के लिए उपयोग कर सकते हैं , जैसे:

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy my_strategy = IMMEDIATE;

प्रकार और चर के बीच अंतर करने के लिए एक नामकरण सम्मेलन होना एक अच्छा विचार है:

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_type;
strategy_type my_strategy = IMMEDIATE;

1
लेकिन ओपी एक गुमनाम
एनम

क्या मैं केवल टाइप नहीं कर सकता enum MyEnum {} myVar;और फिर myVarनिम्नानुसार चर का उपयोग कर सकता हूं :myVar = SOMEENUMCONSTANT;
Mushy

451

यह इंगित करने योग्य है कि आपको इसकी आवश्यकता नहीं है typedef। आप इसे निम्न की तरह कर सकते हैं

enum strategy { RANDOM, IMMEDIATE, SEARCH };
enum strategy my_strategy = IMMEDIATE;

यह एक स्टाइल प्रश्न है कि क्या आप पसंद करते हैं typedef। इसके बिना, यदि आप गणना प्रकार को संदर्भित करना चाहते हैं, तो आपको उपयोग करने की आवश्यकता है enum strategy। इसके साथ, आप बस कह सकते हैं strategy

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


6
यह स्वीकृत उत्तर नहीं होना चाहिए क्योंकि यह गलत है। आप enum रणनीति का उपयोग नहीं कर सकते {...}; C में - आप इसे C ++ में कर सकते हैं और करना चाहिए।
क्लीयर

19
@ क्लेयर: यह कोड पूरी तरह से काम करता है। यहां एक कामकाजी उदाहरण है: ideone.com/T0YV17 ध्यान दें कि यह enumदोनों लाइनों पर कीवर्ड का उपयोग करता है ।
रिचीहिंडले

या "टंकण Enum रणनीति {RANDOM, IMMEDIATE, SEARCH} strategy_t;" और एनम का उपयोग करने वाले देव, जो भी चाहें सम्मेलन का उपयोग कर सकते हैं।
एंडी नगेंट

यह उत्कृष्ट काम करता है: enum strategy { RANDOM, IMMEDIATE, SEARCH }; तब जब आप उस enum का एक उदाहरण चाहते हैं: `enum strategy myEnum;
user3629249

2
@AndyNugent ऐसा नहीं करते! * _t प्रकार
osvein

58

आप strategyदो बार घोषणा करने का प्रयास कर रहे हैं , और इसीलिए आपको उपरोक्त त्रुटि मिल रही है। बिना किसी शिकायत के निम्नलिखित काम करता है (साथ संकलित gcc -ansi -pendantic -Wall):

#include <stdio.h>

enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE;

int main(int argc, char** argv){
    printf("strategy: %d\n", strategy);

    return 0;
}

यदि उपरोक्त के बजाय, दूसरी पंक्ति को बदल दिया गया था:

...
enum { RANDOM, IMMEDIATE, SEARCH } strategy;
strategy = IMMEDIATE;
...

चेतावनियों से, आप आसानी से अपनी गलती देख सकते हैं:

enums.c:5:1: warning: data definition has no type or storage class [enabled by default]
enums.c:5:1: warning: type defaults to int in declaration of strategy [-Wimplicit-int]
enums.c:5:1: error: conflicting types for strategy
enums.c:4:36: note: previous declaration of strategy was here

तो संकलक डिफ़ॉल्ट प्रकार के साथ strategy = IMMEDIATEबुलाया चर की घोषणा के लिए ले लियाstrategyint , लेकिन इस नाम के साथ चर की पिछली घोषणा पहले से ही थी।

हालाँकि, यदि आपने main()फ़ंक्शन में असाइनमेंट रखा है, तो यह एक मान्य कोड होगा:

#include <stdio.h>

enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE;

int main(int argc, char** argv){
    strategy=SEARCH;
    printf("strategy: %d\n", strategy);

    return 0;
}

48

जब आप कहें

enum {RANDOM, IMMEDIATE, SEARCH} strategy;

आप एक एकल उदाहरण चर बनाते हैं, जिसे एक अनाम एनम की 'रणनीति' कहा जाता है। यह करने के लिए एक बहुत ही उपयोगी चीज नहीं है - आपको एक टाइपिडिफ की आवश्यकता है:

typedef enum {RANDOM, IMMEDIATE, SEARCH} StrategyType; 
StrategyType strategy = IMMEDIATE;

9
यह उपयोगी क्यों नहीं है? यदि मुझे इस प्रकार के नाम की परवाह नहीं है, तो मुझे इसे क्यों देना चाहिए? यहाँ केवल एक ही उद्देश्य था कि चर का नाम दिया जाए, इसलिए इसके लिए नए मान निर्दिष्ट करना संभव है।
MSalters

3
मैंने कहा कि यह बहुत उपयोगी नहीं था, और मुझे विश्वास नहीं है कि यह है। निश्चित रूप से, मैं इस पैटर्न का उपयोग अपने कोड में नहीं करता हूं। YMMV।

3
@HorseSMith एक अनाम एनम बहुत उपयोगी नहीं है क्योंकि आपके पास उस प्रकार का कोई अन्य चर या फ़ंक्शन पैरामीटर या वापसी मान नहीं हो सकता है। यदि एक चर आप की जरूरत है, तो यह ठीक है।
बॉब स्टीन

3
अनाम एनम का उपयोग नहीं करने वाला कोई व्यक्ति यह साबित नहीं करता है कि उनका कोई उपयोग नहीं है। आपको टाइपडेफ की जरूरत नहीं है। कुछ कोड दिशानिर्देश (kernel.org/doc/Documentation/CodingStyle) भी इसे हतोत्साहित करते हैं।
मार्टिंकवुव

2
यह जवाब ALSO भ्रामक है। टार्क का उत्तर केवल यहीं है।
नाइटपूल

13

जैसा कि लिखा गया है, आपके कोड में कुछ भी गलत नहीं है। क्या आप सुनिश्चित हैं कि आपने कुछ ऐसा नहीं किया है

int strategy;
...
enum {RANDOM, IMMEDIATE, SEARCH} strategy;

त्रुटि संदेश किन रेखाओं की ओर इशारा करते हैं? जब यह कहता है कि "रणनीति की पिछली घोषणा" यहाँ थी, तो "यहाँ" क्या है और यह क्या दर्शाता है?


6
उन्होंने शायद strategy = IMMEDIATE;फ़ाइल-स्कोप में किया था । सभी कार्यों के बाहर फाइल-स्कोप पर असाइनमेंट नहीं हो सकता है। इसलिए संकलक ने त्रुटि से सबसे अच्छा करने की कोशिश की और यह मान लिया कि वह int strategy = IMMEDIATE;किस बिंदु पर संघर्ष हुआ है।
जोहान्स शाउब - १६:०२ पर

2
यह सबसे अच्छा जवाब है, यह दर्दनाक है अन्य जवाब में इतना श्लेष्मा भ्रम है।
खोलना

12

@ThoAppelsin ने अपनी टिप्पणी में सवाल पोस्ट करने के लिए सही है। प्रश्न में पोस्ट किया गया कोड स्निपेट मान्य है और कोई त्रुटि नहीं है। त्रुटि आपके पास होनी चाहिए क्योंकि आपके सी स्रोत फ़ाइल के किसी अन्य स्थान पर अन्य खराब सिंटैक्स। enum{a,b,c};तीन प्रतीकात्मक स्थिरांक ( और ) को परिभाषित करता है a, जो क्रमशः मूल्यों के साथ पूर्णांक होते हैं , और जब हम इसका उपयोग करते हैं, क्योंकि हम आमतौर पर विशिष्ट पूर्णांक मान के बारे में परवाह नहीं करते हैं, हम प्रतीकात्मक निरंतर नाम के अर्थ के बारे में अधिक परवाह करते हैं। इसका मतलब है कि आपके पास यह हो सकता है:bc012enum

#include <stdio.h>
enum {a,b,c};
int main(){
  printf("%d\n",b);
  return 0;
}

और यह आउटपुट होगा 1

यह भी मान्य होगा:

#include <stdio.h>
enum {a,b,c};
int bb=b;
int main(){
  printf("%d\n",bb);
  return 0;
}

और पहले की तरह ही आउटपुट देगा।

अगर तुम यह करते हो:

enum {a,b,c};
enum {a,b,c};

आपको एक त्रुटि होगी, लेकिन यदि आप ऐसा करते हैं:

enum alfa{a,b,c};
enum alfa;

आपको कोई त्रुटि नहीं होगी।

तुम यह केर सकते हो:

enum {a,b,c};
int aa=a;

और aaमूल्य के साथ एक पूर्णांक चर होगा 0। लेकिन आप यह भी कर सकते हैं:

enum {a,b,c} aa= a;

और एक ही प्रभाव होगा (वह है, aaएक intसाथ होने के नाते0 मूल्य के )।

आप यह भी कर सकते हैं:

enum {a,b,c} aa= a;
aa= 7;

और मूल्य के साथ aaहोगाint7

क्योंकि आप के उपयोग के साथ प्रतीकात्मक निरंतर परिभाषा नहीं दोहरा सकते हैं enum, जैसा कि मैंने पहले कहा है, आपको टैग का उपयोग करना होगा यदि आप intके उपयोग के साथ var घोषित करना चाहते हैं enum:

enum tag1 {a,b,c};
enum tag1 var1= a;
enum tag1 var2= b;

इसका उपयोग typedefआपको enum tag1चर को परिभाषित करने के लिए हर बार लिखने से सुरक्षित करना है । typedefआप के साथ बस टाइप कर सकते हैं Tag1:

typedef enum {a,b,c} Tag1;
Tag1 var1= a;
Tag1 var2= b;

आप यह भी कर सकते हैं:

typedef enum tag1{a,b,c}Tag1;
Tag1 var1= a;
enum tag1 var2= b;

अंतिम बात यह है कि जब से हम परिभाषित प्रतीकात्मक स्थिरांक के बारे में बात कर रहे हैं enum, तो इसका उपयोग करते समय बड़े अक्षरों का उपयोग करना बेहतर होता है, उदाहरण के लिए:

enum {A,B,C};

के बजाय

enum {a,b,c};

10

यह ध्यान देने योग्य है कि C ++ में आप एक टाइप किए गए कथन की आवश्यकता के बिना एक नए प्रकार को परिभाषित करने के लिए "एनम" का उपयोग कर सकते हैं।

enum Strategy {RANDOM, IMMEDIATE, SEARCH};
...
Strategy myStrategy = IMMEDIATE;

मुझे यह दृष्टिकोण बहुत अधिक अनुकूल लगता है।

[संपादित करें - C ++ स्थिति स्पष्ट की - मूल रूप से मेरे पास यह था, फिर इसे हटा दिया!]


हां, आपको C ++ में एनमेट्स (या स्ट्रक्चर्स, यूनियनों आदि) के साथ टाइपडीफ का उपयोग कभी नहीं करना चाहिए।

17
यह प्रश्न C के लिए है, C ++ के लिए नहीं है। सी में, उपरोक्त कोड अमान्य है - आपको या तो उपयोग करना होगा typedef, या enumचर घोषणा में भी निर्दिष्ट करना होगा : enum Strategy {RANDOM, IMMEDIATE, SEARCH}; ... enum Strategy myStrategy = IMMEDIATE;
पावेल मिनाएव

@ तिरछा - मेरा बुरा। मेरे पास मूल रूप से "सी ++" था, फिर कुछ शोध किए जो कि विरोधाभास लग रहे थे।
रोडी

@ मुझे लगता है कि इसका उपयोग करने के लाभों का वर्णन करने वाला एक अलग उत्तर होना चाहिए enum Strategy। मैंने ऐसा किया, नीचे देखें।
जोहान्स शाउब -

8

घोषणा को लेकर असमंजस की स्थिति प्रतीत हो रही है।

जब निम्नलिखित के रूप में strategyपहले आता है {RANDOM, IMMEDIATE, SEARCH},

enum strategy {RANDOM, IMMEDIATE, SEARCH};

आप एक नए प्रकार का नाम बना रहे हैं enum strategy। हालांकि, चर घोषित करते समय, आपको enum strategyस्वयं का उपयोग करने की आवश्यकता होती है। तुम सिर्फ उपयोग नहीं कर सकते strategy। अतः निम्नलिखित अमान्य है।

enum strategy {RANDOM, IMMEDIATE, SEARCH};
strategy a;

जबकि, निम्नलिखित मान्य है

enum strategy {RANDOM, IMMEDIATE, SEARCH};

enum strategy queen = RANDOM;
enum strategy king = SEARCH;
enum strategy pawn[100];

जब strategyआता है {RANDOM, IMMEDIATE, SEARCH}, तो आप एक अनाम एनम बना रहे हैं और फिर strategyउस प्रकार का एक चर घोषित कर रहे हैं ।

तो अब, आप कुछ ऐसा कर सकते हैं

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = RANDOM;

हालाँकि, आप किसी अन्य प्रकार के चर की घोषणा नहीं कर सकते enum {RANDOM, IMMEDIATE, SEARCH}क्योंकि आपने कभी इसका नाम नहीं लिया है। अतः निम्नलिखित अमान्य है

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
enum strategy a = RANDOM;

आप दोनों परिभाषाओं को भी जोड़ सकते हैं

enum strategy {RANDOM, IMMEDIATE, SEARCH} a, b;

a = RANDOM;
b = SEARCH;
enum strategy c = IMMEDIATE;

Typedef जैसा कि पहले उल्लेख किया गया है कि एक छोटे चर घोषणा बनाने के लिए उपयोग किया जाता है।

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;

अब आपने संकलक को बताया है जो इसके enum {RANDOM, IMMEDIATE, SEARCH}लिए समान है strategy। तो अब आप स्वतंत्र strategyरूप से चर प्रकार के रूप में उपयोग कर सकते हैं । आपको enum strategyअब टाइप करने की जरूरत नहीं है। निम्नलिखित अब मान्य है

strategy x = RANDOM;

आप पाने के लिए enum नाम के साथ Typedef को भी जोड़ सकते हैं

typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy;

इस पद्धति का उपयोग करने के लिए इस तथ्य के अलावा बहुत अधिक लाभ नहीं है कि अब आप उपयोग कर सकते हैं strategyऔर enum strategyNameपरस्पर विनिमय कर सकते हैं ।

typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy;

enum strategyName a = RANDOM;
strategy b = SEARCH;

1
बहुत बढ़िया जवाब। मैं इस तरह से लिखी गई enum परिभाषाओं में भी आया हूँ: typedef enum strategy {RANDOM, IMMEDIATE, SEARCH} strategyया typedef enum strategy {RANDOM, IMMEDIATE, SEARCH} strategy_type। क्या इसका कोई फायदा है typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy? क्या आप इन्हें अपने उत्तर में शामिल करने पर विचार करेंगे, पूर्णता के लिए?
tjalling

हाँ। मैंने अपना उत्तर संशोधित कर दिया। मेरे ज्ञान के अनुसार, सामान्य मामले में कोई बड़ा फायदा नहीं है।
कन्फ्यूज

2
महान, आपका जवाब अब यह सब शामिल है, धन्यवाद। शर्म की बात है कि यह अब तक उत्तरों की सूची में कम से कम नहीं है, क्योंकि यह उचित स्पष्टीकरण के साथ मूल प्रश्न को स्पष्ट रूप से संबोधित करता है।
tjalling

2

यदि आप गणना के लिए नाम की घोषणा करते हैं तो कोई त्रुटि नहीं होगी।

यदि घोषित नहीं किया गया है, तो आपको एक का उपयोग करना होगा typedef:

enum enum_name {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;

यह एक त्रुटि प्रदर्शित नहीं करेगा ...


2

मेरा पसंदीदा और केवल इस्तेमाल किया गया निर्माण हमेशा था:

typedef enum MyBestEnum
{
    /* good enough */
    GOOD = 0,
    /* even better */
    BETTER,
    /* divine */
    BEST
};

मुझे विश्वास है कि इससे आपकी समस्या दूर हो जाएगी। नए प्रकार का उपयोग करना मेरे दृष्टिकोण से सही विकल्प है।


1

तारक का जवाब सबसे अच्छा है।

एनम चर्चा के अधिकांश एक लाल हेरिंग है।

इस कोड स्निपेट की तुलना करें: -

int strategy;
strategy = 1;   
void some_function(void) 
{
}

जो देता है

error C2501: 'strategy' : missing storage-class or type specifiers
error C2086: 'strategy' : redefinition

इस के साथ जो कोई समस्या नहीं के साथ संकलित करता है।

int strategy;
void some_function(void) 
{
    strategy = 1;   
}

चर strategy को डिक्लेरेशन या किसी फंक्शन आदि के अंदर सेट करने की आवश्यकता होती है। आप वैश्विक स्तर पर विशेष रूप से - मनमाने ढंग से सॉफ्टवेयर - असाइनमेंट नहीं लिख सकते हैं।

तथ्य यह है कि वह int के बजाय enum {RANDOM, IMMEDIATE, SEARCH} का उपयोग करता था, केवल इस हद तक प्रासंगिक है कि इसने लोगों को भ्रमित कर दिया है जो इससे आगे नहीं देख सकते हैं। प्रश्न में पुनर्परिभाषित त्रुटि संदेश दिखाते हैं कि यह लेखक ने गलत किया है।

तो अब आपको यह देखने में सक्षम होना चाहिए कि नीचे दिए गए उदाहरण में से पहला गलत क्यों है और अन्य तीन ठीक हैं।

उदाहरण 1. गलत!

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
void some_function(void) 
{
}

उदाहरण 2. अधिकार।

enum {RANDOM, IMMEDIATE, SEARCH} strategy = IMMEDIATE;
void some_function(void) 
{
}

उदाहरण 3. अधिकार।

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
void some_function(void) 
{
    strategy = IMMEDIATE;
}

उदाहरण 4. अधिकार।

void some_function(void) 
{
    enum {RANDOM, IMMEDIATE, SEARCH} strategy;
    strategy = IMMEDIATE;
}

यदि आपके पास एक काम करने का कार्यक्रम है, तो आपको इन स्निपेट को अपने कार्यक्रम में पेस्ट करने में सक्षम होना चाहिए और देखना होगा कि कुछ संकलन और कुछ नहीं।


0

मैंने जीसीसी के साथ प्रयास किया और अपनी आवश्यकता के लिए आया था मुझे अंतिम विकल्प का उपयोग करने के लिए मजबूर किया गया था, त्रुटि के साथ संकलन करने के लिए।

typedef enum राज्य {a = 0, b = 1, c = 2} राज्य ;

typedef enum state {a = 0, b = 1, c = 2} state;

typedef enum state old; // New type, alias of the state type.
typedef enum state new; // New type, alias of the state type.

new now     = a;
old before  = b;

printf("State   now = %d \n", now);
printf("Sate before = %d \n\n", before);

newC परिवार में पहचानकर्ताओं का एक बुरा विकल्प है क्योंकि C ++ में एक ऑपरेटर है।
jww

0

सी

enum stuff q;
enum stuff {a, b=-4, c, d=-2, e, f=-3, g} s;

घोषणा जो sपूर्ण प्रकार और घोषणा के साथ एक हस्ताक्षरित पूर्णांक की एक अस्थायी परिभाषा के रूप में कार्य करती है जो qकार्यक्षेत्र में अपूर्ण प्रकार के साथ हस्ताक्षरित पूर्णांक की एक अस्थायी परिभाषा के रूप में कार्य करता है (जो कि पूर्ण प्रकार के दायरे में हल होता है क्योंकि प्रकार परिभाषा कहीं भी मौजूद है गुंजाइश) (किसी भी अस्थायी परिभाषा की तरह, पहचानकर्ता qऔर sएक ही प्रकार intया enum stuffकई बार के अपूर्ण या पूर्ण संस्करण के साथ पुन: घोषित किया जा सकता है लेकिन केवल एक बार दायरे में परिभाषित किया जाता है अर्थात int q = 3; और केवल एक उप-भाग में पुनर्परिभाषित किया जा सकता है, और केवल परिभाषा के बाद प्रयोग करने योग्य)। इसके अलावा, आप केवल enum stuffएक बार पूर्ण प्रकार का उपयोग कर सकते हैं क्योंकि यह एक प्रकार की परिभाषा के रूप में कार्य करता है।

इसके लिए एक कंपाइलर एन्यूमरेशन टाइप डेफिनिशन enum stuffभी फाइल स्कोप (प्रयोग करने योग्य पहले और नीचे) के साथ-साथ फॉरवर्ड टाइप डिक्लेरेशन में प्रस्तुत की जाती है (टाइप enum stuffमें कई डिक्लेरेशन हो सकते हैं लेकिन स्कोप में केवल एक ही डेफिनिशन / पूरा हो सकता है और एक सबसकोप में इसे फिर से परिभाषित किया जा सकता है) । यह भी एक संकलक निर्देश स्थानापन्न करने के रूप में कार्य arvalue साथ 0, bसाथ -4, cसाथ 5, dसाथ -2, eसाथ -3, fसाथ -1और gसाथ -2वर्तमान क्षेत्र में। एन्यूमरेशन स्थिरांक अब परिभाषा के बाद एक अलग एनम में अगले पुनर्परिवर्तन तक लागू होते हैं जो समान स्कोप स्तर पर नहीं हो सकते।

typedef enum bool {false, true} bool;

//this is the same as 
enum bool {false, true};
typedef enum bool bool;

//or
enum bool {false, true};
typedef unsigned int bool;

//remember though, bool is an alias for _Bool if you include stdbool.h. 
//and casting to a bool is the same as the !! operator 

टैग नाम स्थान enum, struct और संघ द्वारा साझा अलग है और बाद प्रकार कीवर्ड (enum, struct या संघ) सी यानी में से उपसर्ग होना चाहिए enum a {a} b, enum a cऔर इस्तेमाल किया जाना चाहिए नहीं a c। क्योंकि टैग नामस्थान पहचानकर्ता नामस्थान के लिए अलग है, enum a {a} bकी अनुमति है, लेकिन enum a {a, b} bइसलिए नहीं है क्योंकि स्थिरांक वैसा ही नाम स्थान में है जैसा कि चर पहचानकर्ता, पहचानकर्ता नाम स्थान। typedef enum a {a,b} bइसलिए भी अनुमति नहीं है क्योंकि टाइप किए गए नाम पहचानकर्ता नामस्थान का हिस्सा हैं।

enum boolC में निम्नलिखित पैटर्न का प्रकार और स्थिरांक निम्नलिखित हैं:

+--------------+-----+-----+-----+
|   enum bool  | a=1 |b='a'| c=3 |  
+--------------+-----+-----+-----+
| unsigned int | int | int | int |  
+--------------+-----+-----+-----+

+--------------+-----+-----+-----+
|   enum bool  | a=1 | b=-2| c=3 |  
+--------------+-----+-----+-----+
|      int     | int | int | int |  
+--------------+-----+-----+-----+

+--------------+-----+---------------+-----+
|   enum bool  | a=1 |b=(-)0x80000000| c=2 |
+--------------+-----+---------------+-----+
| unsigned int | int |  unsigned int | int |
+--------------+-----+---------------+-----+

+--------------+-----+---------------+-----+
|   enum bool  | a=1 |b=(-)2147483648| c=2 |
+--------------+-----+---------------+-----+
| unsigned int | int |  unsigned int | int |
+--------------+-----+---------------+-----+

+-----------+-----+---------------+------+
| enum bool | a=1 |b=(-)0x80000000| c=-2 |
+-----------+-----+---------------+------+
|    long   | int |      long     |  int |
+-----------+-----+---------------+------+

+-----------+-----+---------------+------+
| enum bool | a=1 | b=2147483648  | c=-2 |
+-----------+-----+---------------+------+
|    long   | int |      long     |  int |
+-----------+-----+---------------+------+

+-----------+-----+---------------+------+
| enum bool | a=1 | b=-2147483648 | c=-2 |
+-----------+-----+---------------+------+
|    int    | int |      int      |  int |
+-----------+-----+---------------+------+

+---------------+-----+---------------+-----+
|   enum bool   | a=1 | b=99999999999 | c=1 |
+---------------+-----+---------------+-----+
| unsigned long | int | unsigned long | int |
+---------------+-----+---------------+-----+

+-----------+-----+---------------+------+
| enum bool | a=1 | b=99999999999 | c=-1 |
+-----------+-----+---------------+------+
|    long   | int |      long     |  int |
+-----------+-----+---------------+------+

यह C में ठीक संकलित करता है:

#include <stdio.h>
enum c j;
enum c{f, m} p;
typedef int d;
typedef int c;
enum c j;
enum m {n} ;
int main() {
  enum c j;
  enum d{l};
  enum d q; 
  enum m y; 
  printf("%llu", j);
}

सी ++

C ++ में, enums का एक प्रकार हो सकता है

enum Bool: bool {True, False} Bool;
enum Bool: bool {True, False, maybe} Bool; //error

इस स्थिति में, स्थिरांक और पहचानकर्ता सभी के पास एक ही प्रकार, बूल और एक त्रुटि होगी यदि कोई संख्या उस प्रकार द्वारा प्रतिनिधित्व नहीं की जा सकती है। शायद = 2, जो एक बूल नहीं है। इसके अलावा, सही, गलत और बूल कम मामले नहीं हो सकते हैं अन्यथा वे भाषा के कीवर्ड के साथ टकराएंगे। एक enum में एक सूचक प्रकार भी नहीं हो सकता है।

सी ++ में एनम के नियम अलग हैं।

#include <iostream>
c j; //not allowed, unknown type name c before enum c{f} p; line
enum c j; //not allowed, forward declaration of enum type not allowed and variable can have an incomplete type but not when it's still a forward declaration in C++ unlike C
enum c{f, m} p;
typedef int d;
typedef int c; // not allowed in C++ as it clashes with enum c, but if just int c were used then the below usages of c j; would have to be enum c j;
[enum] c j;
enum m {n} ;
int main() {
  [enum] c j;
  enum d{l}; //not allowed in same scope as typedef but allowed here 
  d q;
  m y; //simple type specifier not allowed, need elaborated type specifier enum m to refer to enum m here
  p v; // not allowed, need enum p to refer to enum p
  std::cout << j;
}

C ++ में Enums चर अब केवल अहस्ताक्षरित पूर्णांक आदि नहीं हैं, वे Enum प्रकार के भी हैं और केवल Enum में स्थिरांक दिए जा सकते हैं। यह हालांकि दूर डाली जा सकती है।

#include <stdio.h>
enum a {l} c;
enum d {f} ;
int main() {
  c=0; // not allowed;
  c=l;
  c=(a)1;
  c=(enum a)4;
  printf("%llu", c); //4
}

Enum कक्षाएं

enum struct के समान है enum class

#include <stdio.h>
enum class a {b} c;
int main() {
  printf("%llu", a::b<1) ; //not allowed
  printf("%llu", (int)a::b<1) ;
  printf("%llu", a::b<(a)1) ;
  printf("%llu", a::b<(enum a)1);
  printf("%llu", a::b<(enum class a)1) ; //not allowed 
  printf("%llu", b<(enum a)1); //not allowed
}

स्कोप रिज़ॉल्यूशन ऑपरेटर अभी भी गैर-स्कॉप्ड एनम के लिए उपयोग किया जा सकता है।

#include <stdio.h>
enum a: bool {l, w} ;
int main() {
  enum a: bool {w, l} f;
  printf("%llu", ::a::w);
}

लेकिन क्योंकि w को दायरे में किसी और चीज के रूप में परिभाषित नहीं किया जा सकता है, ::wऔर इसके बीच कोई अंतर नहीं है::a::w

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