वास्तविक कारण एक तरफ सी और सी ++ के बीच एक मूल अंतर के लिए नीचे आता है, और दूसरी तरफ जावा और सी # (केवल कुछ उदाहरणों के लिए)। ऐतिहासिक कारणों से, यहाँ पर चर्चा सी + + के बजाय सी के बारे में बात करती है, लेकिन (जैसा कि आप शायद पहले से ही जानते हैं) सी ++ सी का काफी प्रत्यक्ष वंशज है, इसलिए सी के बारे में जो कहता है वह सी ++ के समान ही लागू होता है।
हालाँकि वे काफी हद तक भुला दिए जाते हैं (और कभी-कभी उनके अस्तित्व को भी नकार दिया जाता है), UNIX के पहले संस्करणों को असेंबली भाषा में लिखा गया था। अधिकांश (यदि पूरी तरह से नहीं) सी का मूल उद्देश्य विधानसभा भाषा से उच्च स्तर की भाषा के लिए यूनिक्स था। आशय का हिस्सा उच्च स्तर की भाषा में जितना संभव हो उतना ऑपरेटिंग सिस्टम लिखना था - या इसे दूसरी दिशा से देखना, उस राशि को कम करना जो विधानसभा भाषा में लिखी जानी थी।
इसे पूरा करने के लिए, सी को हार्डवेयर तक पहुंच के लगभग समान स्तर प्रदान करने की आवश्यकता थी जैसा कि विधानसभा की भाषा ने किया था। PDP-11 (एक उदाहरण के लिए) मैंने विशिष्ट पते के लिए I / O रजिस्टर किया। उदाहरण के लिए, आप यह जांचने के लिए एक मेमोरी लोकेशन पढ़ेंगे कि क्या सिस्टम कंसोल पर कोई कुंजी दबाई गई थी। उस स्थान पर एक बिट सेट किया गया था जब डेटा पढ़ने के लिए प्रतीक्षा की जा रही थी। फिर आप उस कुंजी के ASCII कोड को पुनः प्राप्त करने के लिए किसी अन्य निर्दिष्ट स्थान से एक बाइट पढ़ेंगे जिसे दबाया गया था।
इसी तरह, यदि आप कुछ डेटा प्रिंट करना चाहते हैं, तो आप किसी अन्य निर्दिष्ट स्थान की जांच करेंगे, और जब आउटपुट डिवाइस तैयार हो जाएगा, तो आप अपना डेटा अभी तक किसी अन्य निर्दिष्ट स्थान पर लिखेंगे।
ऐसे उपकरणों के लिए लेखन ड्राइवरों का समर्थन करने के लिए, सी ने आपको कुछ पूर्णांक प्रकार का उपयोग करके एक मनमाना स्थान निर्दिष्ट करने की अनुमति दी, इसे एक पॉइंटर में बदल दिया और स्मृति में उस स्थान को पढ़ा या लिखा।
बेशक, यह एक बहुत ही गंभीर समस्या है: पृथ्वी पर हर मशीन ने अपनी स्मृति को 1970 के दशक के शुरुआती दिनों से पीडीपी -11 तक पहचान नहीं दिलाई। इसलिए, जब आप उस पूर्णांक को लेते हैं, तो उसे एक सूचक में परिवर्तित करें, और फिर उस सूचक के माध्यम से पढ़ें या लिखें, जो आप प्राप्त करने जा रहे हैं उसके बारे में कोई भी उचित गारंटी नहीं दे सकता है। बस एक स्पष्ट उदाहरण के लिए, पढ़ना और लिखना हार्डवेयर में अलग रजिस्टरों को मैप कर सकता है, इसलिए आप (सामान्य मेमोरी के विपरीत) यदि आप कुछ लिखते हैं, तो इसे वापस पढ़ने की कोशिश करें, जो आप पढ़ते हैं वह आपके द्वारा लिखे गए से मेल नहीं खा सकता है।
मैं कुछ संभावनाएं देख सकता हूं जो छोड़ देता है:
- सभी संभव हार्डवेयर के लिए एक इंटरफ़ेस परिभाषित करें - उन सभी स्थानों के निरपेक्ष पते निर्दिष्ट करें जिन्हें आप किसी भी तरह से हार्डवेयर के साथ बातचीत करने के लिए पढ़ना या लिखना चाहते हैं।
- पहुँच के उस स्तर को प्रतिबंधित करें, और यह तय करें कि जो कोई भी ऐसी चीजें करना चाहता है, उसे विधानसभा भाषा का उपयोग करने की आवश्यकता है।
- लोगों को ऐसा करने की अनुमति दें, लेकिन उनके द्वारा लक्षित किए गए हार्डवेयर के मैनुअल को पढ़ने के लिए (उदाहरण के लिए) उनके पास छोड़ दें, और उनके द्वारा उपयोग किए जाने वाले हार्डवेयर को फिट करने के लिए कोड लिखें।
इनमें से, 1 पर्याप्त रूप से पूर्व-निर्धारित लगता है कि यह शायद ही आगे चर्चा के लायक है। 2 मूल रूप से भाषा के मूल इरादे को दूर कर रहा है। तीसरे विकल्प के रूप में अनिवार्य रूप से केवल एक ही वे सभी पर उचित विचार कर सकते हैं छोड़ देता है।
एक अन्य बिंदु जो काफी बार आता है वह पूर्णांक प्रकारों का आकार है। सी "स्थिति" लेता int
है जो वास्तुकला द्वारा सुझाए गए प्राकृतिक आकार का होना चाहिए। इसलिए, अगर मैं 32-बिट वैक्स का प्रोग्रामिंग कर रहा हूं, तो int
शायद 32 बिट्स होना चाहिए, लेकिन अगर मैं 36-बिट यूनीवैक प्रोग्रामिंग कर रहा हूं, int
तो शायद 36 बिट्स (और इसी तरह) होना चाहिए। यह केवल 36 प्रकार के कंप्यूटर के लिए एक ऑपरेटिंग सिस्टम लिखने के लिए उचित नहीं है (और यह भी संभव नहीं हो सकता है) केवल उन प्रकारों का उपयोग करके जो 8 बिट के गुणकों के आकार की गारंटी हैं। शायद मैं सिर्फ सतही हो रहा हूं, लेकिन यह मुझे लगता है कि अगर मैं 36-बिट मशीन के लिए एक ओएस लिख रहा था, तो मैं शायद एक ऐसी भाषा का उपयोग करना चाहता हूं जो 36-बिट प्रकार का समर्थन करती है।
भाषा के दृष्टिकोण से, यह अभी भी अपरिभाषित व्यवहार की ओर जाता है। यदि मैं सबसे बड़ा मूल्य लेता हूं जो 32 बिट्स में फिट होगा, तो 1 जोड़ने पर क्या होगा? विशिष्ट 32-बिट हार्डवेयर पर, यह रोल करने जा रहा है (या संभवतः किसी प्रकार का हार्डवेयर दोष फेंक सकता है)। दूसरी ओर, अगर यह 36-बिट हार्डवेयर पर चल रहा है, तो यह बस ... एक जोड़ देगा। यदि भाषा ऑपरेटिंग सिस्टम लिखने में सहायता करने वाली है, तो आप व्यवहार की गारंटी नहीं दे सकते हैं - आपको बस दोनों प्रकारों के आकार और ओवरफ्लो के व्यवहार को एक से दूसरे में भिन्न होने की अनुमति देनी होगी।
Java और C # उस सब को नजरअंदाज कर सकते हैं। वे लेखन ऑपरेटिंग सिस्टम का समर्थन करने के इरादे से नहीं हैं। उनके साथ, आपके पास कुछ विकल्प हैं। एक हार्डवेयर समर्थन बनाने के लिए है कि वे क्या मांग करते हैं - चूंकि वे 8, 16, 32 और 64 बिट्स प्रकार की मांग करते हैं, बस उन हार्डवेयर का निर्माण करते हैं जो हर आकार का समर्थन करते हैं। अन्य स्पष्ट संभावना भाषा के लिए केवल अन्य सॉफ़्टवेयर के शीर्ष पर चलने के लिए है जो वे परिवेश प्रदान करते हैं, जो चाहे अंतर्निहित हार्डवेयर चाहे।
ज्यादातर मामलों में, यह वास्तव में या तो / या पसंद नहीं है। बल्कि, कई कार्यान्वयन दोनों का थोड़ा सा करते हैं। आप सामान्य रूप से एक ऑपरेटिंग सिस्टम पर चलने वाले JVM पर जावा चलाते हैं। अधिक बार नहीं, ओएस सी में लिखा जाता है, और सी ++ में जेवीएम। यदि जेवीएम एआरएम सीपीयू पर चल रहा है, तो संभावना बहुत अच्छी है कि सीपीयू में एआरएम के जेजेल एक्सटेंशन शामिल हैं, जावा की जरूरतों के लिए हार्डवेयर को अधिक बारीकी से दर्जी करने के लिए, इसलिए सॉफ्टवेयर में कम आवश्यकता होती है, और जावा कोड तेजी से (या कम) चलता है धीरे-धीरे, वैसे भी)।
सारांश
C और C ++ ने अपरिभाषित व्यवहार किया है, क्योंकि किसी को भी एक स्वीकार्य विकल्प परिभाषित नहीं है जो उन्हें वह करने की अनुमति देता है जो वे करने का इरादा रखते हैं। C # और Java एक अलग दृष्टिकोण लेते हैं, लेकिन यह दृष्टिकोण C और C ++ के लक्ष्यों के साथ खराब (यदि बिल्कुल भी) फिट बैठता है। विशेष रूप से, न तो मनमाने ढंग से चुने गए हार्डवेयर पर सिस्टम सॉफ़्टवेयर (जैसे ऑपरेटिंग सिस्टम) लिखने का एक उचित तरीका प्रदान करता है। दोनों आम तौर पर अपने काम करने के लिए मौजूदा सिस्टम सॉफ्टवेयर (आमतौर पर C या C ++ में लिखे गए) द्वारा दी गई सुविधाओं पर निर्भर करते हैं।