दलील
के समारोह जांच कॉल क्योंकि समस्याओं वहाँ अच्छी तरह से दिखाई दे रहे हैं: क्यों सरणियों बस कार्यों के लिए सरणियों के रूप में, पारित नहीं कर रहे हैं मूल्य द्वारा एक प्रति के रूप में?
पहले एक पूरी तरह से व्यावहारिक कारण है: Arrays बड़ा हो सकता है; उन्हें मूल्य से पारित करने की सलाह नहीं दी जा सकती है क्योंकि वे स्टैक आकार से अधिक हो सकते हैं, खासकर 1 9 70 के दशक में। पहले कंपाइलर पीडीपी -7 पर लगभग 9 केबी रैम के साथ लिखे गए थे।
भाषा में एक और तकनीकी कारण भी है। तर्कों के साथ फ़ंक्शन कॉल के लिए कोड जेनर करना मुश्किल होगा जिसका आकार संकलन समय पर ज्ञात नहीं है। आधुनिक सी में परिवर्तनीय लंबाई सरणी सहित सभी सरणी के लिए, बस कॉल स्टैक पर पते डाल दिए जाते हैं। पता का आकार निश्चित रूप से जाना जाता है। यहां तक कि रन-टाइम आकार की जानकारी वाले विस्तृत सरणी प्रकार वाली भाषाएं भी ढेर पर उचित वस्तुओं को पास नहीं करती हैं। ये भाषाएं आम तौर पर लगभग "हैंडल" पास करती हैं, जो सी ने प्रभावी रूप से 40 वर्षों तक भी किया है। जॉन स्कीट here देखें और एक सचित्र स्पष्टीकरण वह संदर्भित करता है (एसआईसी) here।
अब एक भाषा यह एक आवश्यकता बना सकती है कि एक सरणी में हमेशा एक पूर्ण प्रकार हो; यानी जब भी इसका उपयोग किया जाता है, आकार सहित इसकी पूरी घोषणा दिखाई देनी चाहिए। यह सब के बाद, संरचनाओं से सी को क्या आवश्यक है (जब उन्हें एक्सेस किया जाता है)। नतीजतन, संरचनाओं को मूल्य से कार्यों के लिए पारित किया जा सकता है। सरणी के लिए पूर्ण प्रकार की आवश्यकता के साथ-साथ फ़ंक्शन कॉल आसानी से संकलित करने और अतिरिक्त लंबाई तर्कों को पारित करने की आवश्यकता को रोक देगा: sizeof()
अभी भी कैली के अंदर अपेक्षित काम करेगा। लेकिन कल्पना करें कि इसका क्या अर्थ है। अगर आकार वास्तव में सरणी के तर्क प्रकार का हिस्सा थे, हम एक सरणी आकार के लिए एक अलग कार्य की आवश्यकता होगी:
// for user input.
int average_Ten(int arr[10]);
// for my new Hasselblad.
int average_ThreeTrillionThreehundredninetythreeBillionNinehundredtwentyeightMillionEighthundredsixthousandfourhundred(int arr[16544*12400]);
// ...
तथ्य यह पूरी तरह से गुजर संरचनाओं, जो प्रकार में मतभेद है अगर उनके तत्व अलग करने के लिए तुलनीय होगा में (कहें, 10 इंट तत्वों वाला एक स्ट्रक्चर और 16544 * 12400 वाला एक)। यह स्पष्ट है कि सरणी को अधिक लचीलापन की आवश्यकता है। उदाहरण के लिए, जैसा कि प्रदर्शित किया गया है, आमतौर पर उपयोग करने योग्य लाइब्रेरी फ़ंक्शंस प्रदान नहीं कर सकता जो सरणी तर्क लेता है।
यह "मजबूत टाइपिंग कन्डर्रम" वास्तव में, सी ++ में क्या होता है जब कोई फ़ंक्शन किसी सरणी का संदर्भ लेता है; यही कारण है कि कोई भी ऐसा नहीं करता है, कम से कम स्पष्ट रूप से नहीं। यह उन मामलों के अलावा बेकार होने के बिंदु से पूरी तरह असुविधाजनक है, जो विशिष्ट उपयोगों को लक्षित करते हैं, और जेनेरिक कोड में: सी ++ टेम्पलेट्स संकलन-समय लचीलापन प्रदान करते हैं जो सी
में उपलब्ध है, यदि मौजूदा सी में, वास्तव में सरणी ज्ञात आकार मूल्य से पारित किया जाना चाहिए हमेशा उन्हें एक संरचना में लपेटने की संभावना है। मुझे याद है कि सोलारिस पर कुछ आईपी संबंधित शीर्षकों ने उन्हें पारिवारिक संरचनाओं को उनके साथ सरणी के साथ परिभाषित किया है, जिससे उन्हें प्रतिलिपि बनाने की अनुमति मिलती है।क्योंकि संरचना का बाइट लेआउट तय किया गया था और ज्ञात था, जो समझ में आया।
कुछ पृष्ठभूमि के लिए सी भाषा के विकास का विकास डेनिस रिची द्वारा सी सी के पूर्ववर्ती बीसीपीएल की उत्पत्ति के बारे में कोई सरणी नहीं थी; स्मृति केवल पॉइंटर्स के साथ समरूप रैखिक स्मृति थी।
यह पूरी तरह से (अनावश्यक) प्रतिलिपि बचाता है। सी को गति के लिए डिजाइन किया गया था, सुरक्षा नहीं। – Kninnug
क्योंकि तर्कों के रूप में पारित किए गए सरणी की प्रतिलिपि अधिकतर महंगी और अनावश्यक होगी। इसके अलावा, सी मूल रूप से कार्य तर्कों के रूप में उत्तीर्ण structs का समर्थन नहीं करता था, इसलिए structs से सरणी अलग करने के लिए कोई स्पष्ट डिजाइन विकल्प नहीं था। –
@ किन्नुग एक, निश्चित रूप से, अगर भी वांछित हो, तो पते को पास कर सकता है, जैसा कि कुछ और है। –