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

टीएल; डीआर मुझे अपने कार्यों के मापदंडों को परिभाषित करते समय (स्पष्ट के अलावा, यानी मुझे फ़ंक्शन के साथ क्या करने की आवश्यकता है) को ध्यान में रखने की आवश्यकता है?

0
sfajaja 28 जून 2020, 15:04

2 जवाब

सबसे बढ़िया उत्तर

जैसा कि आप कहते हैं, एक पॉइंटर केवल 4 या 8 बाइट्स का होगा, इसलिए पॉइंटर पास करने के लिए कम मेमोरी की आवश्यकता होगी। बेशक एक पॉइंटर एक्सेस में कुछ और समय खर्च होगा, लेकिन यह कहना मुश्किल है कि अपेक्षाकृत छोटे आकार (और 50 बाइट्स थोड़े छोटे आधुनिक मशीनों के लिए अभी भी थोड़े छोटे हैं) के लिए क्या तेज होगा जब स्ट्रक्चर्स को एक बड़ा पॉइंटर मिलेगा बेहतर है।

सभी में, अधिकांश मामलों के लिए आप प्रदर्शन अंतर पर ध्यान नहीं देंगे, जब तक कि आपके पास बड़े आकार की संरचना न हो (100+ बाइट्स से शुरू होने की बात कहते हैं)।

बेशक, जब आपको किसी संरचना को संशोधित करने की आवश्यकता होती है, तो आपको सूचक की आवश्यकता होती है।

संपादित करें: इससे पहले कि मैं टिप्पणियां प्राप्त करूं, 100+ बाइट्स कुल अनुमान है, यह बहुत अधिक या पहले से ही 50 के लायक हो सकता है।

2
Koen du Buf 28 जून 2020, 12:17

शुरुआती दिनों में, K & R C ने आपको मूल्य के आधार पर संरचनाएं पास नहीं करने दीं। प्रतिलिपि बनाने का एकमात्र तरीका memcpy() (या आपका स्वयं का कार्यान्वयन) था। आईएसओ सी ने तब कॉपी और असाइनमेंट को परिभाषित किया, लेकिन पारंपरिक ज्ञान यह था कि आप वास्तव में डेटा की प्रतिलिपि बनाने से बचना चाहते थे: मेमोरी एक्सेस महंगा है।

वह सिद्धांत आज भी "ट्रूअर" है, लेकिन हम जो निष्कर्ष निकालते हैं, वह उनके सिर पर बदल गया है: हम कभी-कभी निहित <से बचने के लिए अधिक स्पष्ट रूप से कॉपी करते हैं। / em> "रीड-थ्रू" रैम के लिए सभी तरह से। कारण यह है कि आधुनिक कोर में कैश होते हैं जिन्हें रैम की तुलना में बहुत कम विलंबता के साथ एक्सेस किया जा सकता है, और गणना बहुत सस्ती हो गई है। हम यह सुनिश्चित करना चाहते हैं कि कैश सामग्री स्वतंत्र है और उसे महंगे रिफ्रेश / राइट-थ्रू की आवश्यकता नहीं है।

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

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

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

2
Peter - Reinstate Monica 17 जुलाई 2020, 17:26