क्या सूचक को पारित करने के बजाय सी में मूल्य के आधार पर संरचना को पारित करने के लिए कोई डाउनसाइड है?
यदि संरचना बड़ी है, तो स्पष्ट रूप से बहुत सारे डेटा की नकल करने का प्रदर्शन पहलू है, लेकिन एक छोटी संरचना के लिए, यह मूल रूप से एक फ़ंक्शन के लिए कई मानों को पारित करने के समान होना चाहिए।
यह शायद और भी दिलचस्प है जब वापसी मूल्यों के रूप में उपयोग किया जाता है। C में केवल फ़ंक्शन से एकल वापसी मान हैं, लेकिन आपको अक्सर कई की आवश्यकता होती है। तो एक सरल उपाय यह है कि उन्हें एक संरचना में रखा जाए और उसे वापस लौटाया जाए।
क्या इसके कोई कारण हैं या इसके खिलाफ हैं?
चूंकि यह हर किसी के लिए स्पष्ट नहीं हो सकता है कि मैं यहां किस बारे में बात कर रहा हूं, मैं एक सरल उदाहरण दूंगा।
यदि आप C में प्रोग्रामिंग कर रहे हैं, तो आप जल्दी या बाद में इस तरह दिखने वाले फ़ंक्शन लिखना शुरू करेंगे:
void examine_data(const char *ptr, size_t len)
{
...
}
char *p = ...;
size_t l = ...;
examine_data(p, l);
यह कोई समस्या नहीं है। एकमात्र मुद्दा यह है कि आपको अपने सहकर्मी के साथ सहमत होना होगा जिसमें पैरामीटर होना चाहिए ताकि आप सभी कार्यों में समान सम्मेलन का उपयोग कर सकें।
लेकिन जब आप उसी तरह की जानकारी वापस करना चाहते हैं तो क्या होता है? आपको आमतौर पर कुछ इस तरह मिलता है:
char *get_data(size_t *len);
{
...
*len = ...datalen...;
return ...data...;
}
size_t len;
char *p = get_data(&len);
यह ठीक काम करता है, लेकिन बहुत अधिक समस्याग्रस्त है। एक वापसी मूल्य एक वापसी मूल्य है, सिवाय इसके कि इस कार्यान्वयन में यह नहीं है। ऊपर से यह बताने का कोई तरीका नहीं है कि फ़ंक्शन get_data को यह देखने की अनुमति नहीं है कि लेन किस बिंदु पर है। और ऐसा कुछ भी नहीं है जो संकलक की जांच करता है कि मूल्य वास्तव में उस सूचक के माध्यम से वापस आ गया है। इसलिए अगले महीने, जब कोई और इसे ठीक से समझे बिना कोड को संशोधित करता है (क्योंकि उसने दस्तावेज़ीकरण नहीं पढ़ा था?) यह बिना किसी सूचना के टूट जाता है, या यह बेतरतीब ढंग से दुर्घटनाग्रस्त होने लगता है।
इसलिए, मैं जो प्रस्ताव प्रस्तुत करता हूं वह सरल संरचना है
struct blob { char *ptr; size_t len; }
उदाहरण इस तरह से लिखे जा सकते हैं:
void examine_data(const struct blob data)
{
... use data.tr and data.len ...
}
struct blob = { .ptr = ..., .len = ... };
examine_data(blob);
struct blob get_data(void);
{
...
return (struct blob){ .ptr = ...data..., .len = ...len... };
}
struct blob data = get_data();
किसी कारण से, मुझे लगता है कि ज्यादातर लोग सहज रूप से check_data को एक पॉवर ब्लॉब में ले जाते हैं, लेकिन मैं ऐसा नहीं करता। यह अभी भी एक सूचक और पूर्णांक प्राप्त करता है, यह सिर्फ इतना स्पष्ट है कि वे एक साथ चलते हैं। और गेट_डेटा मामले में मैंने पहले वर्णित तरीके से गड़बड़ करना असंभव है, क्योंकि लंबाई के लिए कोई इनपुट मूल्य नहीं है, और एक लौटी हुई लंबाई होनी चाहिए।
gettimeofday
इसके बजाय (जैसे ) पॉइंटर्स का उपयोग करना चाहते हैं , और लोग इसे एक उदाहरण के रूप में लेते हैं।
void examine data(const struct blob)
वह गलत है।