C में फ़ंक्शन तर्क के रूप में सरणियों को पारित क्यों नहीं किया जा सकता है?


12

इस टिप्पणी के बाद , मैंने Google को ऐसा करने का प्रयास किया है, लेकिन मेरा google-fu विफल रहा।

लिंक से टिप्पणी:

[...] लेकिन महत्वपूर्ण बात यह है कि सरणियां और संकेत सी में अलग-अलग चीजें हैं।

यह मानते हुए कि आप किसी संकलक एक्सटेंशन का उपयोग नहीं कर रहे हैं, आप आम तौर पर किसी फ़ंक्शन के लिए एक सरणी पास नहीं कर सकते हैं, लेकिन आप एक पॉइंटर को पास कर सकते हैं, और एक पॉइंटर को इंडेक्स कर सकते हैं जैसे कि यह एक ऐरे था।

आप प्रभावी रूप से शिकायत कर रहे हैं कि पॉइंटर्स की कोई लंबाई जुड़ी हुई नहीं है। आपको यह शिकायत करनी चाहिए कि सरणियों को फ़ंक्शन तर्क के रूप में पारित नहीं किया जा सकता है, या यह कि सरणियों को संकेत के रूप में अस्वीकार कर दिया जाता है।


मुझे यकीन नहीं है कि यह उत्तर है, लेकिन एक सरणी के प्रकार का हिस्सा इसका आकार है, इसलिए मेरा मानना ​​है कि आपको हर आकार के लिए एक फ़ंक्शन को परिभाषित करना होगा जिसे आप स्वीकार करना चाहते हैं।
clcto

क्या आप फंक्शन पॉइंटर्स के रूप में हैं ? कृपया प्रश्न स्पष्ट करें।
user949300

2
@ user949300 नहीं, टिप्पणी के संदर्भ से यह बहुत स्पष्ट है; आप किसी फ़ंक्शन को सरणी नहीं दे सकते क्योंकि यह एक पॉइंटर बन जाता है, और वह जानना चाहता है कि ऐसा क्यों है।
डोभाल

@DocBrown rlemon ने इसके लिए एक संपादन का प्रस्ताव रखा।
फ्लोरियन मार्गाइन

जवाबों:


18

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

EDIT: इस लिंक से कुछ हिस्सों को पढ़ने के बाद , मुझे लगता है कि वास्तविक कारण (और इसका कारण है कि संरचनाओं में सरणियों को मूल्य प्रकार के रूप में माना जाता है, जबकि एकमात्र सरणियां नहीं हैं) सी के पूर्ववर्ती बी के लिए पिछड़ी संगतता है । यहाँ डेनिस रिची से उद्धृत है:

[...} समाधान ने टाइप बीसीपीएल और टाइप सी के बीच विकासवादी श्रृंखला में महत्वपूर्ण उछाल का गठन किया। इसने भंडारण में सूचक के भौतिककरण को समाप्त कर दिया, और इसके बजाय सूचक का निर्माण तब किया जब सरणी का नाम एक अभिव्यक्ति में वर्णित है। नियम, जो आज के सी में जीवित रहता है, वह यह है कि सरणी प्रकार के मूल्यों को परिवर्तित किया जाता है, जब वे अभिव्यक्तियों में दिखाई देते हैं, तो सरणी बनाने वाले ऑब्जेक्ट्स में सबसे पहले होते हैं।

इस आविष्कार ने सबसे मौजूदा बी कोड को भाषा के शब्दार्थ में अंतर्निहित बदलाव के बावजूद काम करना जारी रखने में सक्षम बनाया। [..]


5
A मान से पास किया struct Foo { int array[N]; } जा सकता है। और गतिशील और स्थिर आवंटन के इलाज के बारे में पिछले सा ही गड़बड़ (कठोरतम अर्थ में एक सरणी हमेशा एक आकार, के लिए सरणी अनुक्रमण तरह बातें कर रहे हैं एकीकृत अवधारणाएं शामिल लगता संकेत सरणी-टू-सूचक क्षय के साथ मिलकर), तो आपको विस्तार से बता सकता है?

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

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

@RobertHarvey यह अभी भी प्रकार की प्रणाली में एक विषमता है: सब कुछ मान द्वारा पारित किया जाता है, सरणी प्रकारों को छोड़कर (भले ही एक प्रकार का सरणियाँ जो किसी प्रकार का मान मूल्य से पारित हो जाता है), और यह सटीक नोटेशन (कॉल साइट पर दोनों का उपयोग करता है) और फ़ंक्शन हस्ताक्षर में)।

@ डायलेन: यह क्यों प्रासंगिक है, इसके अलावा आपको इसे याद रखना होगा?
रॉबर्ट हार्वे

9

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

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


2
मेरे पास कुछ बोर्ड हैं जिनमें डेटा के लिए 256 बाइट्स RAM और कोड के लिए 2K EEPROM है। आप वहां किसी सरणी की प्रतिलिपि नहीं बनाना चाहते हैं।
जेरी जेरेमिया
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.