क्यों विशिष्ट चर स्थानों में सी चर संग्रहित?

कल मेरे पास एक साक्षात्कार था जहां साक्षात्कारकर्ता ने मुझे स्टोरेज कक्षाओं के बारे में पूछा जहां चर संग्रहित किए जाते हैं।

मेरा उत्तर युद्ध:

Local Variables are stored in Stack.       
Register variables are stored in Register
Global & static variables are stored in data segment.  
The memory created dynamically are stored in Heap.

उसने मुझसे पूछा कि अगला प्रश्न यह था: वे उन विशिष्ट स्मृति क्षेत्र में क्यों संग्रहीत हो रहे हैं? स्थानीय चर नहीं क्यों संग्रहीत हो रहा है < कोड> रजिस्टर (हालांकि मुझे अपने प्रोग्राम में बहुत बार इस्तेमाल होने वाले auto चर की आवश्यकता होती है)? या क्यों वैश्विक या स्थिर चर नहीं stack में संग्रहीत हो रहे हैं?

तब मैं अनजान था। क्रिप्या मेरि सहायता करे।

6
जोड़ा संपादित
विचारों: 1
एक कोड में रजिस्टर चर संग्रहित नहीं किया जा सकता है।
जोड़ा लेखक user703016, स्रोत
स्थानीय चर हमेशा ढेर में संग्रहीत नहीं होते हैं (अक्सर elided या रजिस्टरों में ले जाया जाता है)। पंजीकरण चर हमेशा रजिस्टरों में संग्रहीत नहीं होते हैं (वे अक्सर ढेर में स्थानांतरित होते हैं)। वैश्विक (स्थिर सहित) चर हमेशा डेटा सेगमेंट में संग्रहीत नहीं होते हैं (उन्हें अक्सर टेक्स्ट सेगमेंट में रखा जाता है, या समर्पित मेमोरी मैप्स में)। एक रजिस्टर चर और गैर-रजिस्टर स्थानीय के बीच एकमात्र अंतर यह है कि संकलक उन प्रोग्रामों को अस्वीकार करता है जो एक रजिस्टर चर का पता लेते हैं।
जोड़ा लेखक Dietrich Epp, स्रोत

5 उत्तर

क्योंकि भंडारण क्षेत्र चर के स्कोप और आजीवन निर्धारित करता है।

आप अपनी आवश्यकता के आधार पर एक भंडारण विनिर्देश चुनते हैं, यानी:
आजीवन: वह अवधि जो आप उम्मीद करते हैं कि विशेष चर को जिंदा और वैध होना चाहिए।
स्कोप: दायरा (क्षेत्र) जहां आप चर को सुलभ होने की अपेक्षा करते हैं।

संक्षेप में, प्रत्येक भंडारण क्षेत्र एक अलग कार्यक्षमता प्रदान करता है और आपको विभिन्न कार्यक्षमता क्षेत्रों के लिए विभिन्न कार्यक्षमता की आवश्यकता होती है।

16
जोड़ा
: अगर ऐसा होता है जब हम एक चर fun() {static int a घोषित करते हैं; एक ++;} तो मैं अन्य फ़ंक्शन जा रहा हूं (मान लीजिए fun2 ) और फिर मैं fun() पर वापस आ रहा हूं कि यह पिछले मान को कैसे बनाए रखता है। क्योंकि static का जीवनकाल fun() के अंदर है
जोड़ा लेखक Rasmi Ranjan Nayak, स्रोत
मैं इस जवाब को समझ नहीं पा रहा हूं। माइक्रोप्रोसेसर में गुंजाइश और आजीवन जैसी कोई चीज नहीं है। इस क्षेत्र में कहीं भी कुछ संगत स्मृति क्षेत्र है जो लिफो (ढेर) है।
जोड़ा लेखक Luka Rahne, स्रोत
प्रश्न इस प्रकार के चर कहां संग्रहीत हैं और आप जीवन भर और दायरे के बारे में बात कर रहे हैं। इस तरह से बात करना ठीक है, क्योंकि मानक ने ऐसा कहा था। मैंने मानक नहीं पढ़ा है, लेकिन ऐसा लगता है कि यह ढेर और ढेर के बारे में बात नहीं करता है ताकि आप उन्हें दायरे और जीवनकाल का उपयोग करके समझा सकें।
जोड़ा लेखक Luka Rahne, स्रोत
@ एएलएस, <�कोड> रजिस्टर वास्तव में कुछ भी जो भी अनिवार्य नहीं है। यह सिर्फ एक संकेत है।
जोड़ा लेखक bdonlan, स्रोत
@RasmiRanjanNayak: हाँ, यह उसका पूरा बिंदु है। आप एक चर में एक कोड a चाहते हैं प्रोग्राम के पूरे जीवनकाल में जिंदा रहें, इसलिए आप static संग्रहण चुनते हैं कक्षा, इससे कोई फर्क नहीं पड़ता कि कंपाइलर इस चर को संग्रहीत करता है, मानक वास्तव में इसके बारे में कुछ भी नहीं कहता है और यह एक कार्यान्वयन विवरण है, लेकिन मानक एक स्थिर चर को पूरे जीवन में रहने के लिए अनिवार्य है जीवन भर और अपने राज्य को बनाए रखने।
जोड़ा लेखक Alok Save, स्रोत
@ralu: स्कोप और आजीवन स्टोरेज विनिर्देशों से जुड़े हैं c/c ++ मानक कीवर्ड के माध्यम से प्रदान करता है, static , extern , रजिस्टर आदि मानक जनादेश है कि जब आप इन खोजशब्दों को एक परिवर्तनीय घोषणा पर उपयोग करते हैं तो कार्यान्वयन को उस चर के लिए कुछ दायरे और आजीवन विशेषताओं को सुनिश्चित करना चाहिए। मानक यह नहीं कहता कैसे या जहां इन चरों को सहेजा जा सकता है या कार्यक्षमता कैसे कार्यान्वित की जानी चाहिए। यह एक कार्यान्वयन विवरण है। यह केवल जरूरी है कि उपयोगकर्ता को कण भंडारण वर्ग से जुड़े गुण प्राप्त कर
जोड़ा लेखक Alok Save, स्रोत
@bdonlan: अच्छी तरह से देखा। उस सूची में रजिस्टर एक टाइपो था। वास्तव में रजिस्टर कुछ भी जरूरी नहीं है
जोड़ा लेखक Alok Save, स्रोत
@ralu, सी जैसे प्रोग्रामिंग भाषाएं आपको एक मंच का एक अमूर्त प्रदान करती हैं और संकलित कार्यक्रम की गारंटी एक निश्चित अवलोकन योग्य व्यवहार है जो इस अमूर्तता को समझती है। यदि आप नहीं चाहते हैं कि आपको असेंबलर में प्रोग्राम करना होगा जो आपके प्रोग्रामिंग के लिए विशिष्ट प्रोसेसर की विशेषताओं को लागू करता है।
जोड़ा लेखक Jens Gustedt, स्रोत

सी भाषा परिभाषित नहीं करती है कि वास्तव में किसी भी चर को संग्रहीत किया जाता है। हालांकि, यह तीन भंडारण वर्गों को परिभाषित करता है: स्थैतिक, स्वचालित, और गतिशील।

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

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

ध्यान दें कि स्वचालित चर के लिए रजिस्टर एनोटेशन एक संकेत है - संकलक इसके साथ कुछ भी करने के लिए बाध्य नहीं है, और वास्तव में कई आधुनिक कंपाइलर्स इसे पूरी तरह से अनदेखा करते हैं।

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

यहां मुख्य लेआउट यह है कि सी भाषा मानक केवल कितना समय परिभाषित मूल्य के लिए अस्तित्व में है परिभाषित करता है। और इस जीवनकाल के लिए न्यूनतम सीमा - यह आवश्यक होने से अधिक समय तक रह सकती है। वास्तव में स्मृति में इसे कैसे रखा जाए एक विषय है जिसमें भाषा और पुस्तकालय कार्यान्वयन को महत्वपूर्ण स्वतंत्रता दी जाती है।

12
जोड़ा
@SwanandPurankar, के एंड आर पुराना है। यह एक अच्छी वैचारिक मार्गदर्शिका है, हालांकि, या तो मैं सुनता हूं, लेकिन यदि आप इस तरह की चीजों पर तकनीकी रूप से सही होना चाहते हैं तो वास्तविक स्पेक को संदर्भित करना बेहतर है। सी भाषा विनिर्देश 'ढेर' के बारे में बात नहीं करता है। चाहे ढेर पर कुछ डालना है या नहीं, कार्यान्वयन का विकल्प है। हालांकि, अधिकांश कार्यान्वयन ढेर पर स्थिरता नहीं डालते हैं (हालांकि, दुभाषिया जैसे दुर्लभ अपवाद हैं)।
जोड़ा लेखक bdonlan, स्रोत
हे @ बोडनान, मैंने एक साक्षात्कार में उत्तर दिया कि स्टेटिक्स ढेर पर संग्रहीत हैं। साक्षात्कारकर्ता "जैसे आप गलत हैं .... क्या आपने कभी के एंड आर और ब्ला ब्लाह को वापस कर दिया है" ... तो मेरा जवाब गलत था? के एंड आर के अनुसार क्या है?
जोड़ा लेखक Swanand, स्रोत

यह वास्तव में केवल एक कार्यान्वयन विस्तार है जो सुविधाजनक है।

कंपाइलर, अगर वह चाहता था, तो ढेर पर स्थानीय चर उत्पन्न कर सकता है अगर वह चाहता है।

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

एक और बिंदु स्थानीय चर को ढेर पर नहीं बनाया जाना चाहिए, उन्हें संग्रहित किया जा सकता है और केवल एक रजिस्टर में उपयोग किया जा सकता है यदि संकलक सोचता है कि यह अधिक उपयुक्त है और ऐसा करने के लिए पर्याप्त रजिस्ट्रार हैं।

1
जोड़ा

स्थानीय चर सभी मामलों में रजिस्टरों में संग्रहीत होते हैं, क्योंकि जब आप फ़ंक्शन कॉल करते हैं तो रजिस्टरों को धक्का दिया जाता है और स्टैक से पॉप किया जाता है ऐसा लगता है कि वे ढेर पर हैं।

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

यही कारण है कि आपने और अधिक पूछा, क्योंकि वह निश्चित नहीं था कि क्या आप विषय को गहराई से समझते हैं। तथ्य यह है कि रजिस्टर वैरिएबल लगभग स्टैक पर हैं।

0
जोड़ा
अधिकांश चर डिफ़ॉल्ट रूप से रजिस्टर में चला जाता है। रजिस्टर का उपयोग केवल कंपाइलर को बताने के लिए किया जा सकता है कि इस तरह के परिवर्तनीय को पंजीकरण में जाने के लिए प्राथमिकता है।
जोड़ा लेखक Luka Rahne, स्रोत
"रजिस्टरों को धक्का दिया जाता है ... जब आप फ़ंक्शन कॉल करते हैं" - कुछ हैं, अन्य फ़ंक्शन तर्क धारण कर सकते हैं, अन्य को केवल बुलाए गए फ़ंक्शन द्वारा धक्का दिया जा सकता है अगर ऐसा लगता है कि इसे अधिक रजिस्टरों की आवश्यकता है, और कुछ मामलों में CPUs अपने स्वयं के तंत्र का समर्थन करते हैं रजिस्ट्रार सैन्स स्टैक को सहेजना और पुनर्स्थापित करना (उदाहरण के लिए अल्ट्रास्पैक्स)। साथ ही, स्थानीय सरणी और पाठ डेटा के लिए असामान्य नहीं है - वे रजिस्टरों में फिट होने की संभावना नहीं है, इसलिए स्पष्टीकरण के बिना "स्थानीय ... अधिकांश मामलों में रजिस्टरों में" अंतर्दृष्टि प्रदान नहीं कर रहा है। फिर "रजिस्टर वै
जोड़ा लेखक Tony Delroy, स्रोत
रजिस्टर बेकार नहीं है इसका मतलब है auto और चर के पते को लेने का हस्तक्षेप। तो यह पॉइंटर पैरामीटर के लिए प्रतिबंधित के रूप में एक अनुकूलन संकेत है, उदा।
जोड़ा लेखक Jens Gustedt, स्रोत
आप विभिन्न अवधारणाओं में मिश्रण कर रहे हैं। प्रोसेसर के रजिस्टर्स और सी भाषा के रजिस्टर कीवर्ड। मैं बस यह कह रहा था कि भाषा कीवर्ड क्या निर्दिष्ट करता है, इस तथ्य के साथ बहुत कुछ नहीं करना है कि एक चर (प्रोसेसर के) में एक चर को महसूस किया जाता है या नहीं। यदि आप चाहते हैं कि यह सिर्फ एक गलत नाम है, तो address (कीवर्ड) को addressless से प्रतिस्थापित करें और आप सी में इसका क्या अर्थ है इसके करीब हैं।
जोड़ा लेखक Jens Gustedt, स्रोत

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

0
जोड़ा