2010-12-27 6 views
12
union test 
{ 
int i; 
char ch; 
}t; 
int main() 
{ 
t.ch=20; 
} 

मान लीजिए sizeof(int)==2 और जाने स्मृति पतों टी के लिए आवंटित 2000, 2001
तो जहां है 20 अर्थात t.ch संग्रहीत - 2000 या 2001 में या मशीन के endianness पर निर्भर करता है?यूनियन सदस्यों को कैसे संग्रहीत किया जाता है?

+0

मुझे यकीन नहीं है कि क्या यूनियन-नेस के पास कुछ भी है जहां यूनियन संग्रहीत किया जाता है ... सभी यूनियन प्रकार एक ही स्थान पर स्टोर नहीं करते हैं (यानी, शून्य ऑफसेट पर)? (हालांकि अच्छा सवाल!) –

+3

2001 असंभव है, क्योंकि अनियंत्रित स्मृति पहुंच आर्किटेक्चर के आधार पर या तो धीमी या वर्जित है। –

+0

@ प्लैटिनम अज़ूर: अगर हम केवल int = 20 को परिभाषित करते हैं; तो क्या यह अंतहीनता पर निर्भर नहीं है जहां 20 संग्रहीत है? –

उत्तर

18

C99 मानक (§6.7.2.1.14) का कहना है:

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

(जोर जोड़ा)

साहसिक बयान वास्तव में कहते हैं संघ के प्रत्येक सदस्य को एक ही पता होता है, तो वे सब एक ही पते पर "शुरू" कि। t, t.cht.i के रूप में, पता 2000 पर होना चाहिए, इस प्रकार t.cht.i के पहले बाइट (पता क्रम में) के साथ ओवरलैप होना चाहिए।

क्या इस के संदर्भ में अर्थ है "क्या हुआ अगर मैं t.c सेट करने के बाद t.i पढ़ने की कोशिश मैं मिलता है" में असली दुनिया मंच endianness पर निर्भर करता है, और तथ्यों में एक यूनियन का सदस्य पढ़ने का प्रयास जब आप किसी अन्य में लिखा था सी मानक के अनुसार एक निर्दिष्ट व्यवहार है (§6.2.6.1.6/7, §J.1.1 पर बहाल)।

union 
{ 
    int i; 
    unsigned char ch[sizeof(i)]; 
} t; 

कर

t.i=20; 
:


और क्या मदद करता है (कम से कम, मुझे लगता है कि यह समझना महत्वपूर्ण है और अधिक सरल है) मशीन के endianness को समझने के लिए इस तरह एक संघ है

और उसके बाद t.ch पर दो वर्णों के अंदर क्या दिख रहा है। यदि आप छोटी-छोटी मशीन पर हैं तो आपको t.ch[0]==20 और t.ch[1]==0 मिलेगा, और इसके विपरीत यदि आप एक बड़ी-एंडियन मशीन पर हैं (यदि sizeof(int)==2)। ध्यान दें कि, जैसा कि पहले से ही कहा गया है, यह एक कार्यान्वयन विशिष्ट विवरण है, मानक में अंतहीनता का भी उल्लेख नहीं है।

इसे और भी स्पष्ट करने के लिए: यदि आपके पास 2-बाइट int var-minian मशीन पर 20 से सेट है, तो पता-क्रम में उससे जुड़ी मेमोरी डंप कर, आपको मिलेगा (हेक्साडेसिमल प्रतिनिधित्व में, अंतरिक्ष के आधार पर विभाजित बाइट्स):

14 00 

जबकि एक बड़े endian मशीन पर आप

00 14 

बड़े endian प्रतिनिधित्व देखने के हमारे बिंदु से "अधिक सही" लग रहा है, क्योंकि में मिल जाएगा छोटे एंडियन प्रतिनिधित्व बाइट्स जो पूरेबनाते हैंरिवर्स ऑर्डर में संग्रहीत हैं।


इसके अलावा मैं कह रहा हूँ कि अगर मैं इस कार्य करें:

int a=20; 
printf("%d",* (char*)&a); 

फिर उत्पादन endian सत्ता पर निर्भर नहीं करता है कि क्या यानी 20 2000 या 2001 में संग्रहीत किया जाता है ?

हाँ, यह ऐसा करता है, लेकिन आपके प्रश्न में आप एक और बात पूछ रहे हैं; यह मेरा उदाहरण दिखता है।

+0

धन्यवाद मैटियो। असल में आप और प्लैटिनम अज़ूर विपरीत चीजें कह रहे हैं, इसलिए मैं उलझन में था। –

+1

@ हैपी मित्तल: जैसा कि मैंने अपनी नवीनतम टिप्पणी में समझाया लेकिन यह, मैं आपकी पुरानी टिप्पणी का उपयोग कर रहा था जिसमें एक अंतर-चार-रूपांतरण था। तथ्य यह है कि: शाब्दिक '20' द्वारा प्रतिनिधित्व किया गया एक सोलह-बिट संख्या अभी भी दोनों बाइट्स में संग्रहीत है, इससे कोई फर्क नहीं पड़ता कि आपके आर्किटेक्चर का क्या उपयोग होता है। यह सिर्फ एक बाइट या दूसरा शून्य होगा। यदि आप '257' जैसी संख्या को स्टोर करना चाहते थे, तो दोनों बाइट गैर-शून्य होंगे। –

1

परीक्षण दो बाइट लेगा, और इसलिए पता 2000, 2002 आदि पर आवंटित किया जाएगा और संघ के प्रत्येक उदाहरण के लिए कोई भी मूल्य उस आधार पते से शुरू किया जाएगा।

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

संबंधित मुद्दे