एक संरचना की घोषणा क्यों करें जिसमें केवल सी में एक सरणी हो?


131

मुझे निम्नलिखित कोड वाले कुछ कोड आए:

struct ABC {
    unsigned long array[MAX];
} abc;

इस तरह से एक घोषणा का उपयोग करना कब समझ में आता है?

जवाबों:


184

यह आपको किसी फ़ंक्शन को मान द्वारा पास करने की अनुमति देता है, या किसी फ़ंक्शन से मान द्वारा लौटाता है।

इन संदर्भों में पॉइंटर को क्षय करने वाले सरणियों के विपरीत, संरचनाओं को मूल्य से पारित किया जा सकता है।


1
सरणियों के साथ ऐसा करने से सावधान रहें, 16 या 32 बाइट्स से अधिक, उन कार्यों के लिए जो इनलाइन नहीं हैं: यह उन्हें कॉन्स्ट-रेफरेंस द्वारा पारित करने के लिए अधिक कुशल है, जब तक कि कैली को पहले से ही एक टैम्प कॉपी की आवश्यकता नहीं है, यह नष्ट कर सकता है। यदि कॉल / रिटर्न दूर अनुकूलन नहीं करते हैं, तो मध्यम से बड़े सरणी (हजारों बाइट्स) मूल्य से गुजरने के लिए एक भयानक बात है।
पीटर कॉर्डेस

85

एक और लाभ यह है कि यह आकार को अलग कर देता है इसलिए आपको [MAX]अपने कोड का उपयोग करने की आवश्यकता नहीं है जहाँ भी आप ऐसी वस्तु की घोषणा करते हैं। यह भी हासिल किया जा सकता है

typedef char ABC[MAX];

लेकिन फिर आपको एक बहुत बड़ी समस्या है: आपको इस बात से अवगत होना होगा कि ABCएक सरणी प्रकार है (भले ही आप इसे तब नहीं देख सकते जब आप प्रकार के चर घोषित करते हैं ABC) या फिर आप इस तथ्य से डगमगाएंगे कि ABCकुछ अलग होगा एक फ़ंक्शन तर्क सूची में बनाम एक चर घोषणा / परिभाषा में।

एक और लाभ यह है कि संरचना आपको बाद में अधिक तत्वों को जोड़ने की अनुमति देती है, यदि आपको बहुत सारे कोड को फिर से लिखने के बिना, आवश्यकता होती है।


45

आप एक संरचना की प्रतिलिपि बना सकते हैं और एक फ़ंक्शन से एक संरचना वापस कर सकते हैं।

आप एक सरणी के साथ ऐसा नहीं कर सकते - जब तक कि यह एक संरचना का हिस्सा नहीं है!


26

आप इसे इस तरह से कॉपी कर सकते हैं।

struct ABC a, b;
........
a = b;

एक सरणी के लिए आपको प्रत्येक तत्व को असाइन करने के लिए मेमसीपी फ़ंक्शन या लूप का उपयोग करना होगा ।


6
(इसलिए यह क्लीनर कोड की अनुमति देता है - यह गति आदि में कोई अंतर नहीं करेगा)
जॉन कार्टर

3
यह उपयोगी है। दुर्भाग्य से आप ऐसा नहीं कर सकते (अगर == बी)!?! कितना असंगत है। C ++ के लिए यह एक == ऑपरेटर के लिए दिखता है। सी में यह "बाइनरी == को अमान्य ऑपरेंड" कहता है।
मैट

11

आप स्ट्रिंग जैसे नए प्रकार के डेटा बनाने के लिए संरचना का उपयोग कर सकते हैं । आप परिभाषित कर सकते हैं:

struct String {
    char Char[MAX];
};

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

आशा है कि यह आपके लिए उपयोगी है :)


2
मूल रूप से, यह निकटतम चीज है सी को एक वर्ग बनाना है। मुझे यह उत्तर पसंद है क्योंकि यह इंगित करने के लिए निकटतम है।
नैट सीके

1
सी। सी। मेथड में सी मेथड के रूप में ऐसी कोई भी चीज सादा पुराना डेटा नहीं है। इसका एक = ऑपरेटर है जो डिफ़ॉल्ट रूप से समर्थित है (जो अन्य उत्तर शो ऐसा करने का कारण है), लेकिन यह भ्रामक है और ज्यादातर सी ++ पर लागू होता है, सी। पर नहीं
जोनाथन स्टर्नबर्ग

3
@ जे स्टर्नबर्ग: "विधि" डेटा को "ऑब्जेक्ट्स" से संबंधित होने के रूप में सबरूटीन के बारे में सोचने का एक तरीका है जो वे प्रभावित करते हैं। आप निश्चित रूप से "वस्तुओं" और "विधियों" की "कक्षाएं" बना सकते हैं जो सी में उन पर काम करते हैं। भाषा सिर्फ ऐसी चीजों को औपचारिक रूप से परिभाषित नहीं करती है। यदि आप सी में बेहतर अमूर्त बनाना चाहते हैं, तो चीजों को एक संरचना में भरना आमतौर पर सबसे अच्छा तरीका है।
नैट सीके

इसके अलावा, यदि आप वास्तव में सी में "तरीके" बनाना चाहते हैं, तो आप उन फ़ंक्शन को डेटा के साथ संबद्ध करने के लिए फ़ंक्शन पॉइंटर्स (हाँ, हाँ, मुश्किल सिंटैक्स, डेटा सुरक्षा नहीं, आदि) का उपयोग कर सकते हैं। आपको पहले तर्क में "स्वयं" पास करना होगा (आप इसे "यह" भी नाम दे सकते हैं, यदि आप चाहते हैं), क्योंकि सी। में फ़ंक्शन के अंदर इस सूचक का कोई स्वत: निर्माण नहीं है, बेशक, यह सब जिमनास्टिक है, आपको मिलता है सी ++ में डिफ़ॉल्ट रूप से इस तरह की चीजें, हालांकि यह सच है कि एक बोनस के रूप में ओवरहेड छिपाया जा सकता है ...
बेनपेन

2

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

यदि आप किसी सरणी को नहीं लपेटते हैं struct, तो आप अभी भी typedefइसके लिए घोषणा कर सकते हैं : इसके कुछ फायदे हैं struct- • प्रकार एक बार घोषित किया जाता है, • आकार स्वचालित रूप से सही है, • कोड का इरादा स्पष्ट हो जाता है, • और कोड अधिक बनाए रखने योग्य है - लेकिन आप-सख्त प्रकार-सुरक्षा खो देते हैं, ◦ प्रकार के मूल्यों को कॉपी करने और वापस करने की क्षमता और later अपने कोड के बाकी हिस्सों को तोड़ने के बिना बाद में सदस्यों को जोड़ने की क्षमता। typedefकिसी दिए गए प्रकार के नंगे सरणियों के लिए दो एस केवल विभिन्न प्रकारों का उत्पादन करते हैं यदि वे विभिन्न आकारों के होते हैं। इसके अलावा, यदि आप एक फ़ंक्शन तर्क के typedefबिना उपयोग करते हैं *, तो यह समान char *-सुरक्षा को कम करने के बराबर है ।

संक्षेप में :

typedef struct A_s_s { char m[113]; } A_s_t; // Full type safey, assignable
typedef char   A_c_t[113];                   // Partial type-safety, not assignable

A_s_t          v_s(void);     // Allowed
A_c_t          v_c(void);     // Forbidden

void           s__v(A_s_t);     // Type-safe, pass by value
void           sP_v(A_s_t *);   // Type-safe
void           c__v(A_c_t);     // UNSAFE, just means char * (GRRR!)
void           cP_v(A_c_t *);   // SEMI-safe, accepts any array of 113

1

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

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


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