जब C प्रोग्राम निष्पादित होता है तो क्या डेटा प्रकार के घोषणाकर्ता "int" और "char" रैम में संग्रहीत होते हैं?


74

जब कोई C प्रोग्राम चल रहा होता है, तो डेटा को ढेर या स्टैक पर संग्रहीत किया जाता है। मान रैम पतों में संग्रहीत होते हैं। लेकिन प्रकार संकेतक (जैसे, intया char) के बारे में क्या ? क्या वे भी संग्रहित हैं?

निम्नलिखित कोड पर विचार करें:

char a = 'A';
int x = 4;

मैंने पढ़ा कि A और 4 यहाँ RAM पतों में संग्रहीत हैं। लेकिन क्या aऔर x? सबसे भ्रामक रूप से, निष्पादन कैसे जानता है कि aएक चर है और xएक इंट है? मेरा मतलब है, रैम में कहीं intऔर charउल्लेख किया गया है?

मान लें कि एक मान 10011001 के रूप में रैम में कहीं संग्रहीत है; अगर मैं प्रोग्राम का पालन करता हूं जो कोड निष्पादित करता है, तो मुझे कैसे पता चलेगा कि यह 10011001 एक है charया एक है int?

क्या मुझे समझ नहीं आता कि कैसे कंप्यूटर जानता है, जब यह एक पते जैसे 10001 से एक वेरिएबल का मान पढ़ता है, क्या यह एक है intया char। कल्पना कीजिए कि मैं नामक कार्यक्रम पर क्लिक करता हूं anyprog.exe। तुरंत कोड निष्पादित करना शुरू कर देता है। क्या इस निष्पादन योग्य फ़ाइल में इस बात की जानकारी शामिल है कि संग्रहीत चर प्रकार के हैं intया नहीं char?


24
यह जानकारी रन-टाइम पर पूरी तरह से खो जाती है। आपको (और आपके संकलक) को पहले से सुनिश्चित करना होगा कि मेमोरी की सही व्याख्या की जाएगी। क्या यह उत्तर आपके बाद था?
5gon12eder 19

4
यह नहीं है क्योंकि यह मानता है कि आप जानते हैं कि आप क्या कर रहे हैं, यह आपके द्वारा प्रदान किए गए मेमोरी पते पर जो कुछ भी मिलता है, उसे लेता है, और इसे लिखने के लिए लिखता है। यदि जो कुछ भी लिखा गया था वह पठनीय चरित्र से मेल खाता है, वह अंततः किसी पढ़ने योग्य चरित्र के रूप में किसी के कंसोल पर दिखाई देगा। यदि यह ऐसा नहीं करता है, तो यह अस्पष्ट रूप में दिखाई देगा, या संभवतः एक यादृच्छिक पठनीय चरित्र।
रॉबर्ट हार्वे

22
@ user16307 संक्षिप्त जवाब यह है कि सांख्यिकीय रूप से टाइप की जाने वाली भाषाओं में, जब भी आप एक चार्ट प्रिंट करते हैं, तो कंपाइलर एक अंतर को प्रिंट करने के लिए अलग कोड का उत्पादन करेगा । रनटाइम में अब कोई ज्ञान नहीं है xजो एक चार है, लेकिन यह चार-प्रिंटिंग कोड है जो चलता है, क्योंकि यही वह संकलक है जिसे चुना गया है।
Ixrec

13
@ user16307 यह हमेशा 65 नंबर के द्विआधारी प्रतिनिधित्व के रूप में संग्रहीत किया जाता है। चाहे वह 65 के रूप में मुद्रित हो या ए के कोड पर निर्भर करता है कि आपके कंपाइलर ने इसे प्रिंट करने के लिए उत्पादन किया है। 65 के बगल में कोई मेटाडेटा नहीं है जो कहता है कि यह वास्तव में एक चार या एक इंट (कम से कम, सांख्यिकीय रूप से टाइप की गई भाषाओं में नहीं है)।
Ixrec

2
पूरी तरह से उन अवधारणाओं को समझें जो आप यहां पूछते हैं और उन्हें अपने आप से कार्यान्वित करते हैं, आप एक संकलक पाठ्यक्रम लेना चाहते हैं, उदाहरण के लिए coursera का एक
mucaho

जवाबों:


122

आपके द्वारा कई टिप्पणियों में पोस्ट किए गए प्रश्न को संबोधित करने के लिए (जो मुझे लगता है कि आपको अपनी पोस्ट में संपादित करना चाहिए):

मुझे समझ में नहीं आता है कि कंप्यूटर को कैसे पता चलता है जब यह एक चर या मूल्य से पता करता है जैसे कि 10001 अगर कोई इंट या चार है। कल्पना कीजिए कि मैं anyprog.exe नामक एक कार्यक्रम पर क्लिक करता हूं। तुरंत कोड निष्पादित करना शुरू कर देता है। क्या इस exe फ़ाइल में चर या चार के रूप में संग्रहीत होने के बारे में जानकारी शामिल है?

तो इसमें कुछ कोड डाल देता है। मान लीजिए आप लिखते हैं:

int x = 4;

और मान लें कि यह रैम में संग्रहीत हो जाता है:

0x00010004: 0x00000004

पहला भाग पते का, दूसरा भाग मान का। जब आपका प्रोग्राम (जो मशीन कोड के रूप में निष्पादित होता है) चलता है, तो यह सब देखता 0x00010004है कि यह मूल्य है 0x000000004। यह इस डेटा के प्रकार को 'नहीं' जानता है, और यह नहीं जानता कि इसका उपयोग कैसे किया जाता है।

तो, आपका कार्यक्रम सही काम करने के लिए कैसे पता लगाता है? इस कोड पर विचार करें:

int x = 4;
x = x + 5;

हमारे यहां एक रीड एंड राइट है। जब आपका प्रोग्राम xमेमोरी से पढ़ता है, तो यह 0x00000004वहां मिल जाता है। और आपका प्रोग्राम 0x00000005इसे जोड़ना जानता है । और जिस कारण से आपका प्रोग्राम 'जानता है' यह एक वैध ऑपरेशन है, ऐसा इसलिए है क्योंकि कंपाइलर सुनिश्चित करता है कि ऑपरेशन टाइप-सेफ्टी के माध्यम से मान्य है। आपके कंपाइलर ने पहले ही सत्यापित कर दिया है कि आप जोड़ सकते हैं 4और 5साथ में। इसलिए जब आपका बाइनरी कोड चलता है (निर्गमन), तो उसे वह सत्यापन करने की आवश्यकता नहीं है। यह बस प्रत्येक चरण को आँख बंद करके निष्पादित करता है, यह मानते हुए कि सब कुछ ठीक है (बुरी चीजें तब होती हैं जब वे वास्तव में होते हैं, ठीक नहीं)।

इसके बारे में सोचने का एक और तरीका इस तरह है। मैं आपको इसकी जानकारी देता हूं:

0x00000004: 0x12345678

पहले जैसा समान प्रारूप - बाईं ओर पता, दाईं ओर मान। मान किस प्रकार का है? इस बिंदु पर, आप बस उस मूल्य के बारे में अधिक जानकारी जानते हैं जैसा कि आपका कंप्यूटर कोड निष्पादित करते समय करता है। अगर मैंने आपसे उस मूल्य में 12743 जोड़ने के लिए कहा, तो आप इसे कर सकते हैं। आपको इस बात का कोई अंदाजा नहीं है कि उस ऑपरेशन के नतीजे पूरे सिस्टम पर होंगे, लेकिन दो नंबर जोड़ना एक ऐसी चीज है जो आप वास्तव में अच्छा है, इसलिए आप इसे कर सकते हैं। क्या इससे मूल्य बनता है int? जरूरी नहीं है - आप सभी देखते हैं दो 32-बिट मान और इसके अतिरिक्त ऑपरेटर है।

शायद कुछ भ्रम फिर से डेटा वापस मिल रहा है। अगर हमारे पास है:

char A = 'a';

कंप्यूटर aको कंसोल में कैसे पता चलता है? वैसे, इसके बहुत सारे कदम हैं। सबसे पहले Aस्मृति में s स्थान पर जाना है और इसे पढ़ना है:

0x00000004: 0x00000061

aASCII में हेक्स मूल्य 0x61 है, इसलिए उपरोक्त कुछ ऐसा हो सकता है जिसे आप मेमोरी में देखेंगे। तो अब हमारे मशीन कोड को पूर्णांक मान पता है। इसे प्रदर्शित करने के लिए पूर्णांक मान को वर्ण में बदलना कैसे जानता है? सीधे शब्दों में कहें, संकलक ने उस संक्रमण को बनाने के लिए सभी आवश्यक चरणों में रखना सुनिश्चित किया। लेकिन आपका कंप्यूटर खुद (या प्रोग्राम / एक्सई) को पता नहीं है कि उस डेटा का प्रकार क्या है। वह 32-बिट मान कुछ भी हो सकता है - int, का charआधा double, एक सूचक, एक सरणी का हिस्सा, एक का stringहिस्सा, एक अनुदेश का हिस्सा, आदि।


आपके कंप्यूटर (ऑपरेटिंग सिस्टम) के साथ आपका प्रोग्राम (उदाहरण) एक संक्षिप्त बातचीत हो सकती है।

कार्यक्रम: मैं शुरू करना चाहता हूं। मुझे 20 एमबी मेमोरी की आवश्यकता है।

ऑपरेटिंग सिस्टम: 20 मुक्त एमबी मेमोरी पाता है जो उपयोग में नहीं है और उन्हें सौंपता है

(महत्वपूर्ण नोट यह है कि यह किसी भी 20 मुक्त एमबी मेमोरी को वापस कर सकता है , उन्हें भी सन्निहित होने की आवश्यकता नहीं है। इस बिंदु पर, प्रोग्राम अब ओएस के साथ बात किए बिना मेमोरी के भीतर काम कर सकता है)

कार्यक्रम: मैं मान रहा हूँ कि स्मृति में पहला स्थान 32-बिट पूर्णांक चर है x

(संकलक यह सुनिश्चित करता है कि अन्य चर तक पहुंच कभी भी स्मृति में इस स्थान को नहीं छूएगा। सिस्टम पर ऐसा कुछ भी नहीं है जो कहता है कि पहला बाइट चर है x, या वह चर xएक पूर्णांक है। एक सादृश्य: आपके पास एक बैग है। आप लोगों को बताते हैं। आप केवल इस बैग में पीले रंग की गेंदें डालेंगे। जब कोई बाद में किसी चीज को बैग से बाहर निकालेगा, तो यह चौंकाने वाला होगा कि वे कुछ नीले या घन को बाहर निकाल देंगे - कुछ गलत हो गया है। कंप्यूटर के लिए भी यही होता है: आपका प्रोग्राम अब मान रहा है कि पहला मेमोरी स्पॉट वेरिएबल x है और यह एक पूर्णांक है। यदि मेमोरी के इस बाइट पर कुछ और लिखा जाता है या इसे कुछ और माना जाता है - कुछ भयानक हो गया है। कंपाइलर इस तरह की चीजों को सुनिश्चित करता है। 'ऐसा नहीं होगा)

कार्यक्रम: मैं अब 2पहले चार बाइट्स पर लिखूंगा जहां मैं मान रहा हूं x

कार्यक्रम: मैं 5 को जोड़ना चाहता हूं x

  • एक अस्थायी रजिस्टर में X का मान पढ़ता है

  • अस्थायी रजिस्टर में 5 जोड़ता है

  • अस्थायी रजिस्टर के मूल्य को पहले बाइट में वापस रखता है, जिसे अभी भी माना जाता है x

कार्यक्रम: मैं मान रहा हूँ कि अगले उपलब्ध बाइट चार चर है y

कार्यक्रम: मैं aचर को लिखूंगा y

  • लाइब्रेरी के लिए बाइट मान ज्ञात करने के लिए उपयोग किया जाता है a

  • बाइट उस पते के लिए लिखी जाती है जिसे प्रोग्राम मान रहा है y

कार्यक्रम: मैं की सामग्री प्रदर्शित करना चाहते हैं y

  • दूसरे मेमोरी स्पॉट में मान पढ़ता है

  • बाइट से चरित्र में बदलने के लिए लाइब्रेरी का उपयोग करता है

  • कंसोल स्क्रीन को बदलने के लिए ग्राफिक्स पुस्तकालयों का उपयोग करता है (पिक्सेल को काले से सफेद तक सेट करना, एक लाइन स्क्रॉल करना, आदि)

(और यह यहाँ से चला जाता है)

क्या आप शायद ऊपर लटका हुआ है - क्या होता है जब स्मृति में पहला स्थान अब नहीं है x? या दूसरा अब नहीं है y? जब कोई पढ़ता है तो क्या होता है xएक के रूप में charया yएक सूचक के रूप में? संक्षेप में, बुरी चीजें होती हैं। इनमें से कुछ चीजों में अच्छी तरह से परिभाषित व्यवहार होता है, और कुछ में अपरिभाषित व्यवहार होता है। अपरिभाषित व्यवहार बिल्कुल यही है कि - कुछ भी हो सकता है, कुछ भी नहीं से, कार्यक्रम या ऑपरेटिंग सिस्टम को क्रैश करने के लिए। यहां तक ​​कि अच्छी तरह से परिभाषित व्यवहार दुर्भावनापूर्ण हो सकता है। यदि मैं xअपने प्रोग्राम के लिए एक पॉइंटर को बदल सकता हूं, और अपने प्रोग्राम को पॉइंटर के रूप में उपयोग करने के लिए प्राप्त कर सकता हूं, तो मैं आपके प्रोग्राम को मेरे प्रोग्राम को निष्पादित करना शुरू कर सकता हूं - जो कि हैकर्स करते हैं। संकलक यह सुनिश्चित करने में मदद करने के लिए है कि हम int xएक के रूप में उपयोग नहीं करते हैंstring, और उस प्रकृति की बातें। मशीन कोड स्वयं प्रकारों से अवगत नहीं है, और यह केवल वही करेगा जो निर्देश इसे करने के लिए कहता है। रन-टाइम पर खोजी गई बड़ी मात्रा में जानकारी भी होती है: मेमोरी के कौन से बाइट्स प्रोग्राम को उपयोग करने की अनुमति है? है xपहली बाइट या 12 वीं में शुरू?

लेकिन आप कल्पना कर सकते हैं कि वास्तव में इस तरह के कार्यक्रम (और आप असेंबली भाषा में लिख सकते हैं) कितना भयानक होगा। आप अपने वेरिएबल्स को 'घोषित' करके शुरू करते हैं - आप खुद को बताते हैं कि बाइट 1 है x, बाइट 2 है y, और जैसा कि आप कोड की प्रत्येक पंक्ति लिखते हैं, लोडिंग और स्टोरिंग रजिस्टर, आपको (एक मानव के रूप में) यह याद रखना होगा कि कौन सा है xऔर कौन सा एक है y, क्योंकि सिस्टम का कोई पता नहीं है। और आपको (एक मानव के रूप में) याद रखना होगा कि कौन से प्रकार xऔर yहैं, क्योंकि फिर से - सिस्टम का कोई पता नहीं है।


अद्भुत व्याख्या। केवल आपके द्वारा लिखा गया भाग "इसे प्रदर्शित करने के लिए पूर्णांक मान को किसी वर्ण में बदलना कैसे जानता है? सरल शब्दों में, संकलक ने उस संक्रमण को बनाने के लिए सभी आवश्यक चरणों में रखना सुनिश्चित किया।" अभी भी मेरे लिए धूमिल है। चलो कहते हैं कि सीपीयू ने RAM रजिस्टर से 0x00000061 प्राप्त किया। इस बिंदु से आप कह रहे हैं कि अन्य निर्देश (exe फ़ाइल में) हैं जो उस संक्रमण को बनाते हैं जिसे हम स्क्रीन पर देखते हैं?
user16307

2
@ user16307 हां, अतिरिक्त निर्देश हैं। आपके द्वारा लिखी गई कोड की प्रत्येक पंक्ति संभावित रूप से कई निर्देशों में बदल सकती है। किस वर्ण का उपयोग करना है, यह जानने के लिए निर्देश हैं कि किस पिक्सेल को संशोधित करने के लिए निर्देश हैं और वे किस रंग में बदलते हैं, आदि ऐसे कोड भी हैं जो आप वास्तव में नहीं देखते हैं। उदाहरण के लिए, std :: cout का उपयोग करके आप लाइब्रेरी का उपयोग कर रहे हैं। कंसोल पर लिखने के लिए आपका कोड केवल एक पंक्ति हो सकता है, लेकिन आपके द्वारा कॉल की जाने वाली फ़ंक्शन (पंक्तियाँ) अधिक लाइनें होंगी, और प्रत्येक पंक्ति कई मशीन निर्देशों में बदल सकती है।
शाम

8
@ user16307 Otherwise how can console or text file outputs a character instead of int क्योंकि मेमोरी स्थान की सामग्री को पूर्णांक या अल्फ़ान्यूमेरिक वर्णों के रूप में आउटपुट करने के लिए निर्देशों का एक अलग क्रम है। कंपाइलर चर प्रकारों के बारे में जानता है, और संकलन समय पर निर्देशों का उचित अनुक्रम चुनता है, और इसे EXE में रिकॉर्ड करता है।
चार्ल्स ई। ग्रांट

2
मुझे बाइट कोड (या बाइटकोड) के रूप में "बाइट कोड ही" के लिए एक अलग वाक्यांश मिलेगा, आमतौर पर एक मध्यवर्ती भाषा (जैसे जावा बाइटकोड या एमएसआईएल) को संदर्भित करता है, जो वास्तव में रनटाइम का लाभ उठाने के लिए इस डेटा को संग्रहीत कर सकता है। इसके अलावा यह पूरी तरह से स्पष्ट नहीं है कि "बाइट कोड" उस संदर्भ में क्या माना जाता है। अन्यथा, अच्छा जवाब।
jpmc26

6
@ user16307 C ++ और C # के बारे में चिंता न करें। ये लोग जो कह रहे हैं, वह आपकी मौजूदा समझ से ऊपर है कि कंप्यूटर और कंपाइलर कैसे काम करते हैं। जो आप समझने की कोशिश कर रहे हैं, उन उद्देश्यों के लिए, हार्डवेयर प्रकार, चार या इंट या जो कुछ भी नहीं जानता है। जब आपने संकलक को बताया कि कुछ चर एक int था, तो यह एक मेमोरी स्थान AS IF को संभालने के लिए निष्पादन योग्य कोड उत्पन्न करता था। स्मृति स्थान में ही प्रकारों के बारे में कोई जानकारी नहीं है; यह सिर्फ इतना है कि आपके कार्यक्रम ने इसे एक इंट के रूप में माना जाता है। रनटाइम प्रकार की जानकारी के बारे में आपने जो कुछ भी सुना है उसे भूल जाइए।
एंड्रेस एफ।

43

मुझे लगता है कि आपका मुख्य प्रश्न यह प्रतीत होता है: "यदि प्रकार संकलन-समय पर मिटा दिया जाता है और रनटाइम पर बनाए नहीं रखा जाता है, तो कंप्यूटर को कैसे पता चलता है कि कोड wich intको निष्पादित करना है या इसे कोड के रूप में व्याख्या करना है जो कि इस तरह से व्याख्या करता है char? "

और जवाब है ... कंप्यूटर नहीं करता है। हालाँकि, संकलक को पता है, और इसने पहली बार बाइनरी में सही कोड डाला होगा। यदि चर को टाइप किया गया था char, तो संकलक इसे intप्रोग्राम के रूप में इलाज करने के लिए कोड नहीं डालेगा , यह कोड को यह इलाज करने के लिए डाल देगा char

वहाँ रहे हैं कारणों कार्यावधि में प्रकार बनाए रखने के लिए:

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

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

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

रनटाइम पर प्रकारों को बनाए रखना केवल तभी आवश्यक है जब आप रनटाइम के प्रकारों के साथ कुछ करना चाहते हैं।

हास्केल सबसे सख्त, सबसे कठोर, टाइप-सेफ स्टेटिकली टाइप्ड भाषाओं में से एक है, और हास्केल कंपाइलर्स आमतौर पर सभी प्रकारों को मिटा देते हैं। (प्रकार वर्गों के लिए विधि शब्दकोशों के पारित होने के अपवाद, मुझे विश्वास है।)


3
नहीं! क्यों? उस जानकारी की क्या आवश्यकता होगी? संकलक charबाइनरी में संकलित पढ़ने के लिए कोड आउटपुट करता है । यह एक के लिए कोड का intउत्पादन नहीं करता है byte, यह एक के लिए कोड का उत्पादन नहीं करता है , यह एक पॉइंटर के लिए कोड का उत्पादन नहीं करता है, यह केवल कोड के लिए केवल आउटपुट करता है char। प्रकार के आधार पर कोई रनटाइम निर्णय नहीं लिए जा रहे हैं। आपको प्रकार की आवश्यकता नहीं है यह पूरी तरह से और पूरी तरह से अप्रासंगिक है। सभी प्रासंगिक निर्णय पहले ही संकलन समय पर किए जा चुके हैं।
जोर्ग डब्ल्यू मित्तग

2
वहाँ नहीं है कंपाइलर बस एक बाइनरी में चार मुद्रण के लिए कोड डालता है। अवधि। संकलक जानता है कि उस मेमोरी पते पर, चार है, इसलिए यह बाइनरी में एक चार्ट को प्रिंट करने के लिए कोड डालता है। यदि किसी अजीब कारण के लिए उस मेमोरी पते पर मूल्य चार नहीं होने के लिए होता है , तो, ठीक है, सभी नरक ढीले टूट जाते हैं। मूल रूप से सुरक्षा का एक पूरा वर्ग काम करता है।
डब्ल्यू

2
इसके बारे में सोचें: यदि सीपीयू किसी तरह से डेटा प्रकार के कार्यक्रमों के बारे में जानता था, तो ग्रह पर हर किसी को एक नया सीपीयू खरीदना होगा, कोई भी एक नए प्रकार का आविष्कार करता है। public class JoergsAwesomeNewType {};देख? मैंने अभी एक नए प्रकार का आविष्कार किया है! आपको एक नया सीपीयू खरीदने की आवश्यकता है!
डब्ल्यू

9
नहीं। यह नहीं है। कंपाइलर जानता है कि उसे बाइनरी में कौन सा कोड डालना है। इस जानकारी को आसपास रखने का कोई मतलब नहीं है। यदि आप कोई इंट प्रिट कर रहे हैं, तो कंपाइलर इंट प्रिटिंग के लिए कोड डाल देगा। यदि आप एक char को प्रिंट कर रहे हैं, तो कंपाइलर char को प्रिंट करने के लिए कोड डाल देगा। अवधि। लेकिन यह सिर्फ एक पैटर्न है। एक चार्ट को प्रिंट करने के लिए कोड एक निश्चित तरीके से बिट पैटर्न की व्याख्या करेगा, एक इंट को प्रिंट करने के लिए कोड एक अलग तरीके से बिट की व्याख्या करेगा, लेकिन बिट पैटर्न को अलग करने का कोई तरीका नहीं है जो एक बिट पैटर्न से एक इंट है एक चार है, यह बिट्स का एक तार है।
जोर्ग डब्ल्यू मित्तग

2
@ user16307: "doesnt exe फ़ाइल में यह जानकारी शामिल है कि कौन सा पता किस प्रकार का डेटा है?" शायद। यदि आप डीबग डेटा के साथ संकलित करते हैं, तो डीबग डेटा में चर नाम, पते और प्रकार की जानकारी शामिल होगी। और कभी-कभी उस डीबग डेटा को .exe फ़ाइल (एक बाइनरी स्ट्रीम के रूप में) में संग्रहीत किया जाता है। लेकिन यह निष्पादन योग्य कोड का हिस्सा नहीं है, और इसका उपयोग केवल डिबगर द्वारा ही नहीं किया जाता है।
बेन Voigt

12

कंप्यूटर "पता नहीं" करता है कि पते क्या हैं, लेकिन आपके प्रोग्राम के निर्देशों में क्या बेक किया गया है इसका ज्ञान है।

जब आप एक C प्रोग्राम लिखते हैं जो एक चार वेरिएबल को लिखता है और पढ़ता है, तो कंपाइलर असेंबली कोड बनाता है जो डेटा के उस टुकड़े को कहीं एक चार के रूप में लिखता है, और कहीं और कोई और कोड होता है जो मेमोरी एड्रेस को पढ़ता है और उसे एक चार्ट के रूप में व्याख्या करता है। इन दोनों ऑपरेशनों को एक साथ बांधने का एकमात्र काम उस मेमोरी एड्रेस का स्थान है।

जब यह पढ़ने का समय आता है, तो निर्देश यह नहीं कहते हैं कि "देखें कि डेटा प्रकार क्या है", यह सिर्फ "मेमोरी के रूप में एक फ्लोट के रूप में लोड" जैसा कुछ कहता है। यदि पढ़ने के लिए पता बदल दिया गया है, या कुछ ने उस मेमोरी को एक फ्लोट के अलावा किसी अन्य चीज़ से अधिलेखित कर दिया है, तो सीपीयू खुशी से उस मेमोरी को फ्लोट के रूप में वैसे ही लोड कर देगा, और परिणामस्वरूप सभी प्रकार के अजीब सामान हो सकते हैं।

खराब सादृश्य समय: एक जटिल शिपिंग वेयरहाउस की कल्पना करें, जहां वेयरहाउस मेमोरी है और चीजों को लेने वाले लोग सीपीयू हैं। गोदाम के कार्यक्रम का एक हिस्सा शेल्फ पर विभिन्न वस्तुओं को रखता है। एक अन्य कार्यक्रम गोदाम से वस्तुओं को पकड़ता है और उन्हें बक्से में डालता है। जब उन्हें खींच लिया जाता है, तो उन्हें चेक नहीं किया जाता है, वे बस बिन में चले जाते हैं। पूरे गोदाम में सिंक में काम करने वाली हर चीज सही काम करती है, सही सामान हमेशा सही समय पर सही जगह पर होता है, नहीं तो सब कुछ क्रैश हो जाता है, ठीक एक वास्तविक कार्यक्रम की तरह।


अगर सीपीयू 0x00000061 को एक रजिस्टर में पाता है और उसे लाता है तो आप कैसे समझाएंगे; और कल्पना करें कि कंसोल प्रोग्राम को एक चरित्र के रूप में आउटपुट करना है, इंट नहीं। क्या आपका मतलब है कि उस exe फ़ाइल में कुछ निर्देश कोड हैं जो जानता है कि 0x00000061 का पता एक चार्ट है और ASCII तालिका का उपयोग करके किसी वर्ण में कनवर्ट करता है?
user16307

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

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

1
@ JörgWMittag: वास्तव में। मैंने एक उदाहरण के रूप में एक बफर अतिप्रवाह का उल्लेख करने के बारे में सोचा था, लेकिन यह तय किया कि यह चीजों को और अधिक भ्रमित कर देगा।
whatsisname 10

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

8

यह नहीं है एक बार C को मशीन कोड में संकलित किया जाता है, मशीन बस बिट्स का एक गुच्छा देखती है। उन बिट्स की व्याख्या कैसे की जाती है यह इस बात पर निर्भर करता है कि कुछ अतिरिक्त मेटाडेटा के विपरीत उन पर कौन से ऑपरेशन किए जा रहे हैं।

आपके स्रोत कोड में आपके द्वारा दर्ज किए गए प्रकार केवल संकलक के लिए हैं। यह लेता है कि आप किस प्रकार के डेटा को कहते हैं और इसकी क्षमता के अनुसार, यह सुनिश्चित करने की कोशिश करता है कि डेटा केवल उन तरीकों से उपयोग किया जाता है जो समझ में आते हैं। एक बार कंपाइलर ने आपके स्रोत कोड के तर्क को जांचने में जितना अच्छा काम किया है, वह इसे मशीन कोड में बदल देता है, और टाइप डेटा को छोड़ देता है, क्योंकि मशीन कोड का प्रतिनिधित्व करने का कोई तरीका नहीं है (कम से कम अधिकांश मशीनों पर) ।


मुझे समझ में नहीं आता है कि कंप्यूटर को कैसे पता चलता है जब यह एक चर या मूल्य से पता करता है जैसे कि 10001 अगर कोई इंट या चार है। कल्पना कीजिए कि मैं anyprog.exe नामक एक कार्यक्रम पर क्लिक करता हूं। तुरंत कोड निष्पादित करना शुरू कर देता है। क्या इस exe फ़ाइल में चर या चार के रूप में संग्रहीत होने की जानकारी शामिल है? -
user16307

@ user16307 नहीं, अगर कोई इंट या चार है, तो इसके बारे में कोई अतिरिक्त जानकारी नहीं है। मैं बाद में कुछ उदाहरण सामग्री जोड़ूंगा, यह मानते हुए कि कोई और मुझे इसके लिए नहीं धड़कता है।
8bittree 20

1
@ user16307: exe फ़ाइल में अप्रत्यक्ष रूप से वह जानकारी है। प्रोग्राम को निष्पादित करने वाले प्रोसेसर प्रोग्राम लिखते समय उपयोग किए जाने वाले प्रकारों के बारे में परवाह नहीं करते हैं, लेकिन इसका उपयोग विभिन्न मेमोरी स्थानों तक पहुंचने के लिए उपयोग किए जाने वाले निर्देशों से किया जा सकता है।
बार्ट वैन इनगेन शेनौ

@ user16307 वास्तव में थोड़ी अतिरिक्त जानकारी है। Exe फ़ाइलों को पता है कि एक पूर्णांक 4 बाइट्स है, इसलिए जब आप लिखते हैं "int" एक चर के लिए संकलक जलाशय 4 बाइट्स लिखते हैं और इस प्रकार एक और दूसरे चर के पते की गणना कर सकते हैं।
एबेन स्कोव पेडरसन

1
@ user16307 कोड के बीच int a = 65और char b = 'A'एक बार संकलित किए जाने के बीच कोई व्यावहारिक अंतर (प्रकार के आकार के अनुसार) अंतर नहीं है।

6

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

कुछ ठोस उदाहरण मदद कर सकते हैं। सूसी लिनक्स एंटरप्राइज सर्वर (SLES) 10 पर चलने वाले x86_64 सिस्टम पर नीचे 4.1.2 का उपयोग करके मशीन कोड उत्पन्न किया गया था।

निम्न स्रोत कोड मान लें:

int main( void )
{
  int x, y, z;

  x = 1;
  y = 2;

  z = x + y;

  return 0;
}

यहाँ gcc -Sमेरे द्वारा जोड़े गए टिप्पणियों के साथ उपरोक्त स्रोत (उपयोग ) के अनुसार उत्पन्न विधानसभा कोड का मांस है :

main:
.LFB2:
        pushq   %rbp               ;; save the current frame pointer value
.LCFI0:
        movq    %rsp, %rbp         ;; make the current stack pointer value the new frame pointer value
.LCFI1:                            
        movl    $1, -12(%rbp)      ;; x = 1
        movl    $2, -8(%rbp)       ;; y = 2
        movl    -8(%rbp), %eax     ;; copy the value of y to the eax register
        addl    -12(%rbp), %eax    ;; add the value of x to the eax register
        movl    %eax, -4(%rbp)     ;; copy the value in eax to z
        movl    $0, %eax           ;; eax gets the return value of the function
        leave                      ;; exit and restore the stack
        ret

कुछ अतिरिक्त चीजें हैं जो इस प्रकार हैं ret, लेकिन यह चर्चा के लिए प्रासंगिक नहीं है।

%eaxएक 32-बिट सामान्य प्रयोजन डेटा रजिस्टर है। स्टैक पॉइंटर%rsp को बचाने के लिए 64-बिट रजिस्टर आरक्षित है , जिसमें स्टैक पर धकेल दी गई आखिरी चीज का पता होता है। फ्रेम पॉइंटर को बचाने के लिए आरक्षित 64-बिट रजिस्टर है , जिसमें वर्तमान स्टैक फ्रेम का पता होता है । जब आप कोई फ़ंक्शन दर्ज करते हैं, तो स्टैक पर एक स्टैक फ्रेम बनाया जाता है, और यह फ़ंक्शन के तर्कों और स्थानीय चर के लिए स्थान रखता है। फ़्रेम पॉइंटर से ऑफसेट का उपयोग करके तर्क और चर एक्सेस किए जाते हैं। इस स्थिति में, चर के लिए मेमोरी 12 बाइट्स है "नीचे" पते में संग्रहीत है । %rbpx%rbp

उपरोक्त कोड में, हम निर्देश का उपयोग करके रजिस्टर में x(1, संग्रहीत -12(%rbp)) के पूर्णांक मान को कॉपी करते हैं , जिसका उपयोग 32-बिट शब्दों को एक स्थान से दूसरे स्थान पर कॉपी करने के लिए किया जाता है। हम तब कॉल करते हैं , जो पहले से ही मूल्य में (पर संग्रहीत ) के पूर्णांक मान को जोड़ता है । हम फिर परिणाम को बचाते हैं , जो है । %eaxmovladdly-8(%rbp)%eax-4(%rbp)z

अब इसे बदलते हैं ताकि हम doubleमूल्यों के बजाय मूल्यों के साथ व्यवहार कर रहे हैं int:

int main( void )
{
  double x, y, z;

  x = 1;
  y = 2;

  z = x + y;

  return 0;
}

gcc -Sफिर से दौड़ना हमें देता है:

main:
.LFB2:
        pushq   %rbp                              
.LCFI0:
        movq    %rsp, %rbp
.LCFI1:
        movabsq $4607182418800017408, %rax ;; copy literal 64-bit floating-point representation of 1.00 to rax
        movq    %rax, -24(%rbp)            ;; save rax to x
        movabsq $4611686018427387904, %rax ;; copy literal 64-bit floating-point representation of 2.00 to rax
        movq    %rax, -16(%rbp)            ;; save rax to y
        movsd   -24(%rbp), %xmm0           ;; copy value of x to xmm0 register
        addsd   -16(%rbp), %xmm0           ;; add value of y to xmm0 register
        movsd   %xmm0, -8(%rbp)            ;; save result to z
        movl    $0, %eax                   ;; eax gets return value of function
        leave                              ;; exit and restore the stack
        ret

कई अंतर। इसके बजाय movlऔर addl, हम उपयोग करते हैं movsdऔर addsd(असाइन करते हैं और डबल-सटीक फ़्लोट्स जोड़ते हैं)। में अंतरिम मूल्यों को संग्रहीत करने के बजाय %eax, हम उपयोग करते हैं %xmm0

इसका मतलब है कि जब मैं कहता हूं कि मशीन कोड में "बेक किया हुआ" है। कंपाइलर बस उस विशेष प्रकार को संभालने के लिए सही मशीन कोड उत्पन्न करता है।


4

ऐतिहासिक रूप से , सी को स्मृति माना जाता है जिसमें कई प्रकार के गिने हुए स्लॉट्स होते हैंunsigned char(इसे "बाइट" भी कहा जाता है, हालांकि इसे हमेशा 8 बिट्स की आवश्यकता नहीं होती है)। कोई भी कोड जो मेमोरी में संग्रहीत किसी भी चीज़ का उपयोग करता है, को यह जानना होगा कि जानकारी को किस स्लॉट या स्लॉट में संग्रहीत किया गया था, और पता है कि वहाँ की जानकारी के साथ क्या किया जाना चाहिए [जैसे "पता 123 पर शुरू होने वाले चार बाइट्स की व्याख्या करें: 32-बिट के रूप में 456 फ्लोटिंग-पॉइंट वैल्यू "या" सबसे हाल ही में गणना की गई 16 बिट्स के निचले 16 बिट्स को 345 पते पर शुरू करके स्टोर करें। 678]। मेमोरी खुद ही न तो जान पाएगी और न ही इस बात का ध्यान रख पाएगी कि मेमोरी स्लॉट में स्टोर किए गए वैल्यू का क्या मतलब है। " कोड ने एक प्रकार का उपयोग करके मेमोरी लिखने की कोशिश की और इसे दूसरे के रूप में पढ़ा, लेखन द्वारा संग्रहीत बिट पैटर्न को दूसरे प्रकार के नियमों के अनुसार व्याख्या की जाएगी, जिसके परिणाम कुछ भी हो सकते हैं।

उदाहरण के लिए, यदि कोड को 0x1234567832-बिट में संग्रहित किया जाना था unsigned int, और फिर unsigned intउसके पते और उसके बाद के संस्करण से लगातार दो 16-बिट मानों को पढ़ने का प्रयास किया जाता है, तो यह निर्भर करता है कि कौन सा आधा unsigned intसंग्रहित है जहां, कोड मानों को पढ़ सकता है 0x1234 और 0x5678, या 0x5678 और 0x1234।

C99 मानक, हालाँकि, अब आवश्यकता नहीं है कि स्मृति गिने हुए स्लॉट्स के एक समूह के रूप में व्यवहार करती है जो उनके बिट पैटर्न का प्रतिनिधित्व करने के बारे में कुछ भी नहीं जानते हैं । एक कंपाइलर को व्यवहार करने की अनुमति दी जाती है, हालांकि मेमोरी स्लॉट उन डेटा के प्रकारों के बारे में जानते हैं जो उनमें संग्रहीत हैं, और केवल उन डेटा को अनुमति देगा जो किसी भी प्रकार का उपयोग करके लिखे जाने के अलावा किसी अन्य प्रकार का उपयोग करके लिखे गए unsigned charहैं unsigned charया जैसा लिखा गया था। साथ में; कंपाइलरों को आगे व्यवहार करने की अनुमति दी जाती है, हालांकि मेमोरी स्लॉट में किसी भी कार्यक्रम के व्यवहार को मनमाने ढंग से भ्रष्ट करने की शक्ति और झुकाव है जो उन नियमों के विपरीत फैशन में स्मृति तक पहुंचने की कोशिश करता है।

दिया हुआ:

unsigned int a = 0x12345678;
unsigned short p = (unsigned short *)&a;
printf("0x%04X",*p);

कुछ कार्यान्वयन 0x1234 प्रिंट कर सकते हैं, और अन्य 0x5678 प्रिंट कर सकते हैं, लेकिन C99 मानक के तहत "FRINK RULES!" या कुछ और करते हैं, इस सिद्धांत पर कि यह aहार्डवेयर को शामिल करने के लिए रखने वाले मेमोरी स्थानों के लिए कानूनी होगा जो रिकॉर्ड करता है कि उन्हें लिखने के लिए किस प्रकार का उपयोग किया गया था, और ऐसे हार्डवेयर के लिए किसी भी फैशन में अमान्य पढ़ने के प्रयास का जवाब देने के लिए, जिसमें शामिल हैं "फ्रेंक रूल्स!" आउटपुट होना।

ध्यान दें कि यदि कोई ऐसा हार्डवेयर वास्तव में मौजूद है तो इससे कोई फर्क नहीं पड़ता - तथ्य यह है कि इस तरह के हार्डवेयर कानूनी रूप से मौजूद हो सकते हैं यह कंपाइलरों के लिए कोड उत्पन्न करने के लिए कानूनी बनाता है जो व्यवहार करता है जैसे कि यह ऐसी प्रणाली पर चल रहा है। यदि कंपाइलर यह निर्धारित कर सकता है कि एक विशेष मेमोरी लोकेशन को एक प्रकार के रूप में लिखा जाएगा और दूसरे के रूप में पढ़ा जाएगा, तो यह दिखावा कर सकता है कि यह एक सिस्टम पर चल रहा है जिसका हार्डवेयर इस तरह का निर्धारण कर सकता है, और कंपाइलर लेखक की जो भी डिग्री देखता है, उसके साथ प्रतिक्रिया दे सकता है ।

इस नियम का उद्देश्य संकलक को अनुमति देना था जो जानता था कि किसी प्रकार के बाइट का एक समूह किसी समय में एक विशेष मूल्य रखता है, और यह कि उस प्रकार का कोई मूल्य नहीं लिखा गया था, जिससे उस समूह का अनुमान लगाया जा सके बाइट्स अभी भी उस मूल्य को धारण करेगा। उदाहरण के लिए, एक प्रोसेसर ने बाइट्स के एक समूह को एक रजिस्टर में पढ़ा था, और फिर बाद में उसी जानकारी का फिर से उपयोग करना चाहता था, जबकि यह अभी भी रजिस्टर में था, कंपाइलर मेमोरी से मूल्य को फिर से पढ़ने के बिना रजिस्टर सामग्री का उपयोग कर सकता है। एक उपयोगी अनुकूलन। नियम के पहले दस वर्षों के लिए, इसका उल्लंघन करने का आम तौर पर मतलब होगा कि यदि एक चर को एक प्रकार के अलावा किसी अन्य के साथ लिखा जाता है जो इसे पढ़ने के लिए उपयोग किया जाता है, तो लेखन मूल्य को पढ़ने को प्रभावित कर सकता है या नहीं। कुछ मामलों में ऐसा व्यवहार विनाशकारी हो सकता है, लेकिन अन्य मामलों में हानिरहित हो सकता है,

2009 के आसपास, हालांकि, CLANG जैसे कुछ संकलक के लेखकों ने निर्धारित किया है कि चूंकि मानक संकलक को कुछ भी करने की अनुमति देता है, ऐसे मामलों में जहां मेमोरी एक प्रकार का उपयोग करके लिखी जाती है और दूसरे के रूप में पढ़ी जाती है, संकलक को अनुमान लगाना चाहिए कि प्रोग्राम को कभी भी इनपुट नहीं मिलेगा जो कि प्राप्त कर सकता है ऐसा होने का कारण। चूंकि मानक कहता है कि कंपाइलर को ऐसा कुछ भी करने की अनुमति है, जब ऐसा अमान्य इनपुट प्राप्त होता है, तो कोड केवल उन मामलों में प्रभाव होगा जहां मानक कोई आवश्यकता नहीं लगाता है (और कुछ संकलक लेखकों की दृष्टि में, को छोड़ दिया जाना चाहिए) अप्रासंगिक के रूप में। यह स्मृति के समान होने से उल्लंघनों के उल्लंघन के व्यवहार को बदल देता है, जिसे पढ़ने का अनुरोध दिया जाता है, मनमाने ढंग से उसी प्रकार का उपयोग करके लिखे गए अंतिम मान को वापस कर सकता है जो किसी अन्य प्रकार का उपयोग करके लिखे गए किसी भी हाल के मान को लिखा जाता है।


1
अपरिभाषित व्यवहार का उल्लेख करते समय किसी ऐसे व्यक्ति को छांटना, जो यह नहीं समझता कि कोई आरटीटीआई नहीं है, यह सहज ज्ञान युक्त लगता है
कोल जॉनसन

@ColeJohnson: यह बहुत बुरा है कि 2009 के प्री-कंपाइलरों के 99% द्वारा समर्थित C की बोली के लिए कोई औपचारिक नाम या मानक नहीं है, क्योंकि दोनों शिक्षण दृष्टिकोण और व्यावहारिक रूप से उन्हें मौलिक रूप से विभिन्न भाषाओं में माना जाना चाहिए। चूँकि एक ही नाम को दोनों बोलियों को दिया जाता है, जो 35 वर्षों में कई पूर्वानुमानित और आशाजनक व्यवहारों को विकसित करता है, बोली जो अनुकूलन के कथित उद्देश्य के लिए ऐसे व्यवहारों को बाहर निकालती है, उन चीजों के बारे में बात करते समय भ्रम से बचना मुश्किल होता है जो उनमें अलग तरीके से काम करते हैं ।
सुपरकैट

ऐतिहासिक रूप से C लिस्प मशीनों पर चलता था जो इस तरह के ढीले खेल की अनुमति नहीं देता था। मुझे पूरा यकीन है कि 30 साल पहले देखे गए कई "पूर्वानुमेय और अनुकूलन योग्य व्यवहार" बस वैक्स पर बीएसडी यूनिक्स कहीं भी काम नहीं करते थे।
prosfilaes

@prosfilaes: शायद "1999 से 2009 तक इस्तेमाल किए गए 99% कम्पाइलर" अधिक सटीक होंगे? यहां तक ​​कि जब कंपाइलरों के पास कुछ बदले हुए आक्रामक पूर्णांक अनुकूलन के विकल्प थे, तो वे बस यही विकल्प थे। मुझे नहीं पता कि मैंने 1999 से पहले कभी कोई कंपाइलर देखा है, जिसके पास ऐसा मोड नहीं था जो यह गारंटी नहीं देता था कि दिया int x,y,z;गया एक्सप्रेशन x*y > z1 या 0 के अलावा कुछ भी नहीं करेगा, या जहाँ एलियास उल्लंघन का कोई असर होगा। संकलक को मनमाने ढंग से या तो पुराने या नए मान को वापस करने के अलावा अन्य।
सुपरकैट

1
... जहां unsigned charएक प्रकार का निर्माण करने के लिए उपयोग किए जाने वाले मान "से आए थे"। यदि कोई प्रोग्राम किसी पॉइंटर को विघटित करने के लिए था unsigned char[], तो स्क्रीन पर उसकी हेक्स सामग्री को संक्षेप में दिखाएं, और उसके बाद पॉइंटर को मिटा दें unsigned char[], और बाद में कीबोर्ड से कुछ हेक्स नंबरों को स्वीकार करें, उन्हें एक पॉइंटर पर वापस कॉपी करें, और फिर उस पॉइंटर को देखें , व्यवहार उस मामले में अच्छी तरह से परिभाषित किया जाएगा जहां संख्या टाइप की गई थी जो प्रदर्शित की गई संख्या से मेल खाती है।
सुपरकैट

3

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

आमतौर पर कंपाइलर आपके लिए इस बात का ध्यान रखता है, और यदि आप कुछ गलत करते हैं, तो आपको कंपाइल-टाइम एरर (या चेतावनी) मिलेगा।


मुझे समझ में नहीं आता है कि कंप्यूटर को कैसे पता चलता है जब यह एक चर या मूल्य से पता करता है जैसे कि 10001 अगर कोई इंट या चार है। कल्पना कीजिए कि मैं anyprog.exe नामक एक कार्यक्रम पर क्लिक करता हूं। तुरंत कोड निष्पादित करना शुरू कर देता है। क्या इस exe फ़ाइल में चर या चार के रूप में संग्रहीत होने की जानकारी शामिल है? -
user16307

1
@ user16307 अनिवार्य रूप से नहीं, वह सभी जानकारी पूरी तरह से खो गई है। यह मशीन कोड पर निर्भर है कि उस जानकारी के बिना भी अपना काम ठीक से किया जा सके। सभी कंप्यूटर परवाह करते हैं कि पते पर एक पंक्ति में आठ बिट्स हैं 10001। यह या तो आपकी नौकरी या संकलक की नौकरी है, इस पर निर्भर करता है, मशीन या असेंबली कोड लिखते समय उस तरह से सामान रखने के लिए।
पैंज़रक्रिसिस

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

मेरे प्रश्न को देखो मैंने लिखा था "जब एक सी कार्यक्रम निष्पादित होता है?" अभिप्राय वे अनुदेश कोड के बीच exe फ़ाइल में अप्रत्यक्ष रूप से संग्रहीत हैं और अंततः मेमोरी में जगह लेते हैं? मैं इसे आपके लिए फिर से लिखता हूं: यदि सीपीयू एक रजिस्टर पर 0x00000061 पाता है और इसे प्राप्त करता है; और कल्पना करें कि कंसोल प्रोग्राम को एक चरित्र के रूप में आउटपुट करना है, इंट नहीं। क्या उस exe फ़ाइल (मशीन / बाइनरी कोड) में कुछ निर्देश कोड हैं, जो 0x00000061 का पता जानता है कि एक चार्ट है और ASCII तालिका का उपयोग करके किसी वर्ण में कनवर्ट करता है? यदि ऐसा है तो इसका मतलब है कि चार इंटिग्रेटर्स अप्रत्यक्ष रूप से बाइनरी में हैं ???
user16307

यदि मान 0x61 है और एक चार के रूप में घोषित किया गया है (यानी, 'ए') और आप इसे प्रदर्शित करने के लिए एक रूटीन कहते हैं, तो उस चरित्र को प्रदर्शित करने के लिए एक सिस्टम कॉल होगा। यदि आपने इसे इंट के रूप में घोषित किया है और डिस्प्ले रुटीन को कॉल किया है, तो संकलक कोड को 0x61 (दशमलव 97) को ASCII अनुक्रम 0x39, 0x37 ('9', '7') में परिवर्तित करने के लिए जान लेगा। नीचे पंक्ति: उत्पन्न कोड अलग है क्योंकि संकलक उन्हें अलग तरीके से व्यवहार करना जानता है।
माइक हैरिस

3

आप के बीच भेद करने के लिए है compiletimeऔर runtimeएक हाथ और पर codeऔर dataदूसरी तरफ।

एक मशीन के दृष्टिकोण से यह क्या आप कॉल के बीच कोई अंतर नहीं है codeया instructionsऔर आप क्या कहते हैं data। यह सब संख्या के लिए नीचे आता है। लेकिन कुछ सीक्वेंस - जिसे हम कहेंगे code- कुछ ऐसा करें जो हमें उपयोगी लगे, दूसरों को बस crashमशीन।

सीपीयू द्वारा किया जाने वाला कार्य एक सरल 4 चरण लूप है:

  • दिए गए पते से "डेटा" प्राप्त करें
  • निर्देश को डिकोड करें (यानी संख्या की व्याख्या "एक के रूप में करें" instruction)
  • एक प्रभावी पता पढ़ें
  • परिणाम निष्पादित करें और संग्रहीत करें

इसे निर्देश चक्र कहा जाता है

मैंने पढ़ा कि A और 4 यहाँ RAM पतों में संग्रहीत हैं। लेकिन एक्स और एक्स के बारे में क्या?

aऔर xचर हैं, जो पते के लिए प्लेसहोल्डर हैं, जहां कार्यक्रम चर की "सामग्री" पा सकता है। इसलिए, जब भी चर aका उपयोग किया जाता है, तो प्रभावी रूप से aप्रयुक्त सामग्री का पता होता है।

सबसे भ्रामक रूप से, निष्पादन कैसे जानता है कि ए चर और एक्स एक इंट है?

निष्पादन किसी भी पता नहीं है। परिचय में क्या कहा गया था, सीपीयू केवल डेटा प्राप्त करता है और निर्देश के रूप में इस डेटा की व्याख्या करता है।

Printf समारोह "पता" करने के लिए, इनपुट आप किस तरह इसे में लगा रहे हैं, यानी इसके परिणामस्वरूप कोड सही निर्देश देता है कि कैसे एक विशेष स्मृति खंड से निपटने के लिए बनाया गया है। बेशक, बकवास आउटपुट को प्राप्त करना संभव है: एक पते का उपयोग करके, जहां "% s" के साथ कोई स्ट्रिंग संग्रहीत नहीं है, जिसके printf()परिणामस्वरूप बकवास उत्पादन केवल एक यादृच्छिक मेमोरी स्थान से बंद हो जाता है, जहां 0 ( \0) है।

एक प्रोग्राम के एंट्री-पॉइंट के लिए वही जाता है। C64 के तहत हर ज्ञात पते पर (लगभग) अपने कार्यक्रमों को रखना संभव था। असेंबली-प्रोग्राम एक निर्देश के साथ शुरू किए गए थे, जिसे sysएक पते के बाद कहा जाता sys 49152था : अपने कोडांतरक कोड को रखने के लिए एक आम जगह थी। लेकिन कुछ भी आपको ग्राफिकल डेटा लोड करने से नहीं रोकता है 49152, जिसके परिणामस्वरूप इस बिंदु से "शुरू" होने के बाद मशीन दुर्घटनाग्रस्त हो जाती है। इस मामले में, अनुदेश चक्र "ग्राफिकल डेटा" को पढ़ने और इसे "कोड" के रूप में व्याख्या करने की कोशिश के साथ शुरू हुआ था (जो निश्चित रूप से कोई मतलब नहीं था); प्रभाव कुछ चौंकाने वाले थे;)

मान लें कि एक मान 10011001 के रूप में रैम में कहीं संग्रहीत है; अगर मैं कोड को निष्पादित करने वाला कार्यक्रम हूं, तो मुझे कैसे पता चलेगा कि यह 10011001 एक चार्ट है या एक इंट?

जैसा कि कहा गया है: "संदर्भ" - अर्थात पिछले और अगले निर्देश - डेटा को उस तरह से इलाज करने में मदद करते हैं जैसा हम चाहते हैं। मशीन के नजरिए से, किसी भी मेमोरी लोकेशन में कोई अंतर नहीं है। intऔर charकेवल शब्दावली है, जो समझ में आता है compiletime; के दौरान runtime(एक विधानसभा स्तर पर), वहाँ कोई है charया int

मुझे समझ में नहीं आता है कि कंप्यूटर को कैसे पता चलता है, जब वह 10001 जैसे एक पते से एक चर का मूल्य पढ़ता है, चाहे वह एक इंट या चार हो।

कंप्यूटर कुछ नहीं जानताप्रोग्रामर करता है। संकलित कोड संदर्भ उत्पन्न करता है , जो मनुष्यों के लिए सार्थक परिणाम उत्पन्न करने के लिए आवश्यक है।

क्या इस निष्पादन योग्य फ़ाइल में इस बात की जानकारी शामिल है कि संग्रहीत चर प्रकार int या char के हैं या नहीं

हाँ और नहीं । जानकारी, चाहे वह है intया charखो गया है। लेकिन दूसरी ओर, संदर्भ (निर्देश जो बताते हैं, स्मृति स्थानों से कैसे निपटें, जहां डेटा संग्रहीत है) संरक्षित है; इसलिए स्पष्ट रूप से हां, "जानकारी" अंतर्निहित रूप से उपलब्ध है।


संकलन समय और रनटाइम के बीच अच्छा अंतर।
माइकल ब्लैकबर्न

2

इस चर्चा को हम C भाषा में ही रखते हैं।

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

char a = 'A';
int x = 4;

आइए हम प्रत्येक भाग का विश्लेषण करने का प्रयास करें:

char / int को डेटा प्रकार के रूप में जाना जाता है। ये संकलक को स्मृति आवंटित करने के लिए कहते हैं। के मामले में charयह 1 बाइट और int2 बाइट होगा। (कृपया ध्यान दें कि यह स्मृति आकार फिर से माइक्रोप्रोसेसर पर निर्भर है)।

a / x को पहचानकर्ता के रूप में जाना जाता है। अब ये हैं आप रैम में मेमोरी लोकेशन के लिए दिए गए "यूजर फ्रेंडली" नाम कह सकते हैं।

= संकलक को 'ए' मेमोरी स्थान पर aऔर 4 मेमोरी स्थान पर संग्रहीत करने के लिए कहता है x

इसलिए int / char data type आइडेंटिवर्स का उपयोग केवल कंपाइलर द्वारा किया जाता है, न कि प्रोग्राम निष्पादन के दौरान माइक्रोप्रोसेसर द्वारा। इसलिए उन्हें स्मृति में संग्रहीत नहीं किया जाता है।


ठीक int / char डेटा प्रकार पहचानकर्ता सीधे चर के रूप में मेमोरी में संग्रहीत नहीं होते हैं, लेकिन वे अप्रत्यक्ष रूप से अनुदेश कोड के बीच exe फ़ाइल में संग्रहीत होते हैं और अंततः मेमोरी में जगह लेते हैं? मैं इसे आपके लिए फिर से लिखता हूं: यदि सीपीयू एक रजिस्टर पर 0x00000061 पाता है और इसे प्राप्त करता है; और कल्पना करें कि कंसोल प्रोग्राम को एक चरित्र के रूप में आउटपुट करना है, इंट नहीं। क्या उस exe फ़ाइल (मशीन / बाइनरी कोड) में कुछ निर्देश कोड हैं, जो 0x00000061 का पता जानता है कि एक चार्ट है और ASCII तालिका का उपयोग करके किसी वर्ण में कनवर्ट करता है? यदि ऐसा है तो इसका मतलब है कि चार इंटिग्रेटर्स अप्रत्यक्ष रूप से बाइनरी में हैं ???
user16307

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

2

यहाँ मेरा उत्तर कुछ सरल है और केवल C को संदर्भित करेगा।

नहीं, कार्यक्रम में टाइप जानकारी संग्रहीत नहीं होती है।

intया charसीपीयू के लिए संकेतक नहीं हैं; केवल संकलक के लिए।

कंपाइलर द्वारा बनाए गए exe intमें वेरिएबल के रूप में घोषित किए जाने पर s को हेरफेर करने के निर्देश होंगे int। इसी तरह, यदि चर को ए के रूप में घोषित किया गया था char, तो निर्गमन में हेरफेर करने के निर्देश होंगे char

सी में:

int main()
{
    int a = 65;
    char b = 'A';
    if(a == b)
    {
        printf("Well, what do you know. A char can equal an int.\n");
    }
    return 0;
}

इस कार्यक्रम के प्रिंट होगा अपने संदेश, के बाद से charऔर intहै एक ही मूल्यों रैम में।

अब, यदि आप सोच रहे हैं कि कैसे और एक के printfलिए आउटपुट का प्रबंधन करता है , तो इसका कारण यह है कि आपको "प्रारूप स्ट्रिंग" में निर्दिष्ट करना होगा कि मूल्य का इलाज कैसे करना चाहिए । (उदाहरण के लिए, मान को a के रूप में मानने का मतलब है , और मान को पूर्णांक के रूप में मानने का मतलब है; वैसे ही मूल्य, वैसे भी)।65intAcharprintf
%cchar%d


2
मैं उम्मीद कर रहा था कि कोई व्यक्ति उदाहरण का उपयोग करके उपयोग करेगा printf। @OP: int a = 65; printf("%c", a)आउटपुट देगा 'A'। क्यों? क्योंकि प्रोसेसर परवाह नहीं करता है। इसके लिए, यह सब देखता है बिट्स हैं। आपके कार्यक्रम ने प्रोसेसर को 65 (संयोग से 'A'ASCII के मूल्य ) में संग्रहीत करने के लिए कहा aऔर फिर एक चरित्र का उत्पादन किया, जो खुशी से करता है। क्यों? क्योंकि यह परवाह नहीं है।
कोल जॉनसन

लेकिन कुछ लोग यहाँ C # केस में क्यों कहते हैं, यह कहानी नहीं है? मैं कुछ अन्य टिप्पणियों को पढ़ता हूं और वे C # और C ++ में कहते हैं कि कहानी (डेटा प्रकारों पर जानकारी) अलग है और यहां तक ​​कि सीपीयू भी कंप्यूटिंग नहीं करता है। उस बारे में कोई विचार?
user16307

@ user16307 यदि सीपीयू कंप्यूटिंग नहीं करता है, तो प्रोग्राम नहीं चल रहा है। :) C # के लिए, मुझे नहीं पता, लेकिन मुझे लगता है कि मेरा जवाब वहां भी लागू होता है। C ++ के लिए, मुझे पता है कि मेरा जवाब वहां लागू होता है।
बेन्जीवेबे

0

सबसे निचले स्तर पर, वास्तविक भौतिक सीपीयू में कोई प्रकार नहीं होते हैं (फ्लोटिंग पॉइंट यूनिट्स की अनदेखी)। बिट्स के सिर्फ पैटर्न। एक कंप्यूटर बिट्स के पैटर्न में हेरफेर करके काम करता है, बहुत, बहुत तेज।

वह सब सीपीयू कभी करता है, वह सब कभी कर सकता है। इंट, या चार जैसी कोई चीज नहीं है।

x = 4 + 5

के रूप में निष्पादित करेंगे:

  1. लोड 00000100 रजिस्टर 1 में
  2. लोड 00000101 रजिस्टर 2 में
  3. IAdd रजिस्टर 1 रजिस्टर करने के लिए 2, और रजिस्टर 1 में स्टोर

आईडीडी इंस्ट्रक्शन हार्डवेयर को ट्रिगर करता है जो व्यवहार करता है जैसे कि रजिस्टर 1 और 2 पूर्णांक हैं। यदि वे वास्तव में पूर्णांक का प्रतिनिधित्व नहीं करते हैं, तो सभी प्रकार की चीजें बाद में गलत हो सकती हैं। सबसे अच्छा परिणाम आमतौर पर दुर्घटनाग्रस्त होता है।

यह संकलक पर स्रोत में दिए गए प्रकारों के आधार पर सही निर्देश को चुनने के लिए है, लेकिन सीपीयू द्वारा निष्पादित वास्तविक मशीन कोड में, कहीं भी, कोई प्रकार नहीं हैं।

संपादित करें: ध्यान दें कि वास्तविक मशीन कोड वास्तव में कहीं भी 4, या 5 या पूर्णांक का उल्लेख नहीं करता है। यह बिट्स के सिर्फ दो पैटर्न हैं, और एक निर्देश जो दो बिट पैटर्न लेता है, वे चींटियों को मानते हैं, और उन्हें एक साथ जोड़ते हैं।


0

संक्षिप्त जवाब, प्रकार सीपीयू में संकलित है निर्देश संकलक उत्पन्न करता है।

हालाँकि, जानकारी के प्रकार या आकार के बारे में जानकारी सीधे संग्रहीत नहीं की जाती है, लेकिन कंपाइलर इन सूचनाओं को इन चरों में पहुँच, संशोधन और भंडारण करते समय इस जानकारी पर नज़र रखता है।

निष्पादन कैसे जानता है कि एक चार और एक एक्स एक int है?

यह नहीं है, लेकिन जब कंपाइलर मशीन कोड का उत्पादन करता है, तो यह पता है। एक intऔर charविभिन्न आकारों का हो सकता है। एक आर्किटेक्चर में जहां एक चार बाइट का आकार है और एक इंट 4 बाइट्स है, तब चर xपता 10001 में नहीं है, बल्कि 10002, 10003 और 10004 में भी है। जब कोड को xसीपीयू रजिस्टर में मान लोड करने की आवश्यकता होती है , यह 4 बाइट्स लोड करने के निर्देश का उपयोग करता है। एक लोड करते समय, यह 1 बाइट को लोड करने के लिए अनुदेश का उपयोग करता है।

दोनों निर्देशों में से किसका चयन करें? संकलनकर्ता संकलन के दौरान निर्णय लेता है, यह स्मृति में मूल्यों का निरीक्षण करने के बाद रनटाइम पर नहीं किया जाता है।

ध्यान दें कि रजिस्टर विभिन्न आकारों के हो सकते हैं। इंटेल x86 सीपीयू पर EAX 32 बिट्स चौड़ा है, इसका आधा हिस्सा AX है, जो कि 16 है, और AX को AH और AL, दोनों 8 बिट्स में विभाजित किया गया है।

इसलिए यदि आप एक पूर्णांक (x86 CPUs पर) लोड करना चाहते हैं, तो आप पूर्णांक के लिए MOV निर्देश का उपयोग करते हैं, एक char को लोड करने के लिए आप char के लिए MOV निर्देश का उपयोग करते हैं। उन्हें दोनों एमओवी कहा जाता है, लेकिन उनके पास अलग-अलग ऑप कोड हैं। प्रभावी रूप से दो अलग-अलग निर्देश। चर का प्रकार उपयोग करने के निर्देश में इनकोड किया गया है।

यही बात अन्य ऑपरेशनों के साथ भी होती है। ऑपरेंड के आकार के आधार पर, और इसके अलावा कि वे हस्ताक्षरित या अहस्ताक्षरित हैं, प्रदर्शन करने के लिए कई निर्देश हैं। Https://en.wikipedia.org/wiki/ADD_(x86_instruction) देखें जो विभिन्न संभावित योगों को सूचीबद्ध करते हैं।

मान लें कि एक मान 10011001 के रूप में रैम में कहीं संग्रहीत है; अगर मैं प्रोग्राम को लागू करता हूं जो कोड को निष्पादित करता है, तो मुझे कैसे पता चलेगा कि यह 10011001 एक चार्ट है या एक इंट

सबसे पहले, एक चार्ट 10011001 होगा, लेकिन एक int 00000000 00000000 00000000 10011001 होगा, क्योंकि वे अलग-अलग आकार के हैं (कंप्यूटर पर समान आकार के साथ जैसा कि ऊपर बताया गया है)। लेकिन signed charबनाम के लिए मामले पर विचार करने देता है unsigned char

मेमोरी लोकेशन में जो संग्रहीत किया जाता है उसकी व्याख्या वैसे भी की जा सकती है जैसा आप चाहते हैं। सी कंपाइलर की जिम्मेदारियों का एक हिस्सा यह सुनिश्चित करना है कि एक चर से संग्रहित और पढ़ा गया सुसंगत तरीके से किया जाता है। तो ऐसा नहीं है कि कार्यक्रम को पता है कि मेमोरी स्थान में क्या संग्रहीत है, लेकिन यह हाथ से पहले सहमत है कि यह हमेशा उसी तरह की चीजों को पढ़ेगा और लिखेगा। (कास्टिंग प्रकार जैसी चीजों की गिनती नहीं)।


लेकिन कुछ लोग यहाँ C # केस में क्यों कहते हैं, यह कहानी नहीं है? मैं कुछ अन्य टिप्पणियों को पढ़ता हूं और वे C # और C ++ में कहते हैं कि कहानी (डेटा प्रकारों पर जानकारी) अलग है और यहां तक ​​कि सीपीयू भी कंप्यूटिंग नहीं करता है। उस बारे में कोई विचार?
user16307

0

लेकिन कुछ लोग यहाँ C # केस में क्यों कहते हैं, यह कहानी नहीं है? मैं कुछ अन्य टिप्पणियों को पढ़ता हूं और वे C # और C ++ में कहते हैं कि कहानी (डेटा प्रकारों पर जानकारी) अलग है और यहां तक ​​कि सीपीयू भी कंप्यूटिंग नहीं करता है। उस बारे में कोई विचार?

C # जैसी टाइप-चेक की गई भाषाओं में, कंपाइलर द्वारा टाइप-चेकिंग की जाती है। कोड बेंजी ने लिखा:

int main()
{
    int a = 65;
    char b = 'A';
    if(a == b)
    {
        printf("Well, what do you know. A char can equal an int.\n");
    }
    return 0;
}

बस संकलन करने से मना कर देंगे। इसी तरह अगर आपने एक स्ट्रिंग और पूर्णांक को गुणा करने की कोशिश की (मैं ऐड कहने जा रहा था, लेकिन ऑपरेटर '+' स्ट्रिंग कॉन्फैक्शन से भरा हुआ है और यह सिर्फ काम कर सकता है)।

int a = 42;
string b = "Compilers are awesome.";
double[] c = a * b;

संकलक बस इस सी # से मशीन कोड उत्पन्न करने के लिए, कोई कितना भी अपने स्ट्रिंग यह अप करने के लिए चूमा इन्कार कर देंगे।


-4

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

मैं अस्पष्ट रूप से ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के लिए डिज़ाइन किए गए हार्डवेयर आर्किटेक्चर के बारे में सुनकर याद करता हूं, जो कुछ इसी तरह का था, लेकिन मैं इसे अब नहीं ढूंढ सकता।


3
यह प्रश्न विशेष रूप से बताता है कि यह सी भाषा (लिस्प नहीं) का उल्लेख है, और सी भाषा चर मेटाडेटा को संग्रहीत नहीं करती है। हालांकि ऐसा करने के लिए सी कार्यान्वयन के लिए निश्चित रूप से संभव है, क्योंकि मानक इसे मना नहीं करता है, व्यवहार में ऐसा कभी नहीं होता है। यदि आपके पास प्रश्न के लिए प्रासंगिक उदाहरण हैं, तो कृपया विशिष्ट उद्धरण प्रदान करें और सी भाषा से संबंधित संदर्भ प्रदान करें ।

ठीक है, आप एक लिस्प मशीन के लिए सी कंपाइलर लिख सकते हैं, लेकिन कोई भी इस दिन और सामान्य रूप से लिस्प मशीनों का उपयोग नहीं करता है। ऑब्जेक्ट-ओरिएंटेड आर्किटेक्चर वैसे तो रेकर्सिव था ।
नाथन रिंगो

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

लेकिन कुछ लोग यहाँ C # केस में क्यों कहते हैं, यह कहानी नहीं है? मैं कुछ अन्य टिप्पणियों को पढ़ता हूं और वे C # और C ++ में कहते हैं कि कहानी (डेटा प्रकारों पर जानकारी) अलग है और यहां तक ​​कि सीपीयू भी कंप्यूटिंग नहीं करता है। उस बारे में कोई विचार?
user16307
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.