यदि आप वैध सीमा सुनिश्चित करना चाहते हैं, तो एक तकनीक है जो पूर्णांक मान प्राप्त करने के लिए पॉइंटर अव्यवस्था के छोटे ओवरहेड के साथ आता है - और बहुत सारे बॉयलरप्लेट टाइपिंग। यह अभी भी उपयोगी हो सकता है क्योंकि यह आपको रेंज-चेकिंग कोड लिखने से लाभ देता है जहां यह अन्यथा आवश्यक होगा।
greetings.h:
#ifndef GREETINGS_H
#define GREETINGS_H
struct greetings;
typedef struct greetings Greetings;
extern const Greetings * const Greetings_hello;
extern const Greetings * const Greetings_bye;
extern const Greetings * const Greetings_how;
const char *Greetings_str(const Greetings *g);
int Greetings_int(const Greetings *g);
#endif
greetings.c:
#include "greetings.h"
struct greetings {
const int val;
};
static const Greetings hello = { 0 };
static const Greetings bye = { 1 };
static const Greetings how = { 2 };
const Greetings * const Greetings_hello = &hello;
const Greetings * const Greetings_bye = &bye;
const Greetings * const Greetings_how = &how;
static const char * const Greetings_names[] = {
"hello",
"bye",
"how"
};
const char *
Greetings_str(const Greetings *g)
{
return Greetings_names[g->val];
}
int
Greetings_int(const Greetings *g)
{
return g->val;
}
उदाहरण main.c:
#include <stdio.h>
#include "greetings.h"
void
printTest(const Greetings *greeting)
{
if (greeting == Greetings_how) return;
puts(Greetings_str(greeting));
}
int
main()
{
const Greetings *g = Greetings_hello;
printTest(g);
}
हाँ, बहुत टाइप करने के लिए है, लेकिन आप पूर्ण प्रकार मिलता है और सीमा सुरक्षा। कोई अन्य संकलन इकाई कभी भी struct greetings
को तुरंत चालू नहीं कर सकती है, इसलिए आप पूरी तरह से सुरक्षित हैं।
संपादित करें 2015-07-04: न्यूल के खिलाफ सुरक्षा के लिए, दो संभावनाएं हैं। या तो डिफ़ॉल्ट मान के लिए NULL का उपयोग करें (अब उपयोग किए गए सूचक के बजाय #define Greetings_hello 0
)। यह बहुत सुविधाजनक है, लेकिन डिफॉल्ट एनम वैल्यू के लिए टाइप सुरक्षा को छोड़ देता है, एनयूएलएल किसी भी एनम के लिए इस्तेमाल किया जा सकता है। या यह अमान्य घोषित करने और या तो एक्सेसर तरीकों में इसके लिए जाँच, एक त्रुटि लौटने, या संकलन समय, जैसे में greetings.h पर यह पकड़ने के लिए GCCs __attribute__((nonnull()))
की तरह कुछ का उपयोग करें:
const char *Greetings_str(const Greetings *g)
__attribute__((nonnull(1)));
स्रोत
2015-07-01 15:20:39
यह साफ है, लेकिन स्विच स्टेटमेंट्स में एम्स के साथ थोड़ा बदसूरत काम करता है। – Toby