2013-06-15 2 views
5

मैंने एक दोस्त से सुना है कि सी में दो आयामी सरणी केवल वाक्य रचनात्मक रूप से समर्थित हैं।सी में दो आयामी सरणी सभी तत्वों को संगत बनाने के लिए आवश्यक हैं?

उसने मुझे float[M][N] के बजाय float arr[M * N] का बेहतर उपयोग करने के लिए कहा क्योंकि जीसी जैसे सी कंपाइलर्स गारंटी नहीं दे सकते कि प्रत्येक सिस्टम/प्लेटफॉर्म पर डेटा स्मृति के भीतर श्रृंखला में है।

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

तो पहला सवाल:

क्या वह सही कह रहा है?

दूसरा सवाल:

आप अगर वहाँ एक किताब या एक लेख जहां इस बयान को मिल रहा है पता है?

धन्यवाद + सादर

+0

यह बकवास है। 'फ्लोट [एम * एन]' आपको स्मृति की भौतिक रूप से संकीर्ण हिस्से नहीं देने की आवश्यकता है, और 'फ्लोट [एम] [एन] 'तार्किक रूप से संगत है। –

+1

सी प्रोग्रामिंग भाषा कर्निघान और रिचे द्वारा वहां की सबसे अच्छी किताब है। इसे देखें – 22kar

+1

के एंड आर अच्छा है, लेकिन साल भर अधिक पुराना हो रहा है। इसे आखिरी बार 1 9 88 में संशोधित किया गया था। –

उत्तर

13
  1. नहीं, वह गलत है।

  2. सी मानक देखें। कुछ प्रासंगिक बिट (बोल्ड जोर मेरा):

    6.2.5 प्रकार ¶20

    एक सरणी प्रकार एक विशेष सदस्य ऑब्जेक्ट प्रकार, कहा जाता है के साथ एक समीप आवंटित वस्तुओं की अरिक्त समुच्च्य का वर्णन करता है तत्व प्रकार

    6.7.6.2 सरणी declarators ¶3 (ध्यान दें 142)

    जब कई विशिष्टताओं "की सरणी" निकट हैं, एक बहुआयामी सरणी घोषित किया जाता है।

    6.5.2.1 सरणी subscripting ¶3

    लगातार सबस्क्रिप्ट ऑपरेटरों एक बहुआयामी सरणी वस्तु का एक तत्व को नामित। ... यह इस प्रकार से है कि सरणी पंक्ति-प्रमुख क्रम में संग्रहीत हैं (अंतिम सबस्क्रिप्ट सबसे तेज़ी से भिन्न होता है)।

    और शायद सबसे स्पष्ट रूप से, 6.5.2 में उदाहरण।1 सरणी subscripting ¶4:

    उदाहरण सरणी वस्तु घोषणा

    int x[3][5];

    यहाँ x द्वारा परिभाषित करने पर विचार करें int रों की एक 3 × 5 सरणी है; अधिक सटीक, x तीन तत्व वस्तुओं की एक सरणी है, जिनमें से प्रत्येक पांच int s की एक सरणी है। x[i] अभिव्यक्ति में, जो (*((x)+(i))) के समतुल्य है, x को पहले पर पॉइंटर में परिवर्तित किया गया है, जिसमें पांच int s की प्रारंभिक सरणी है। फिर ix के प्रकार के अनुसार समायोजित किया गया है, जो संकल्पनात्मक रूप से i को ऑब्जेक्ट के आकार से गुणा करने के लिए प्रेरित करता है जिसमें पॉइंटर पॉइंट, अर्थात् पांच int ऑब्जेक्ट्स की एक सरणी है। परिणाम जोड़े गए हैं और पर संकेत लागू किया गया है, प्रत्येक int s की एक सरणी उत्पन्न करें। जब x[i][j] अभिव्यक्ति में उपयोग किया जाता है, तो उस सरणी को बदले में पहली बार पॉइंटर में परिवर्तित किया जाता है, इसलिए x[i][j] एक int उत्पन्न करता है। सी में

बहुआयामी सरणियों बस "सरणियों के सरणियों" कर रहे हैं। वे ठीक काम करते हैं और मानक द्वारा परिभाषित 100% हैं।

आपको comp.lang.c FAQ में Section 6, Arrays and Pointers पढ़ने में भी मदद मिल सकती है।

+0

तो सी मानक कहता है कि कंपाइलर्स को लगातार सरणी स्टोर करना चाहिए। लेकिन क्या वे सभी उस नियम का पालन करते हैं? हो सकता है कि उसका दोस्त किस बारे में बात कर रहा था। मैं सिर्फ उत्सुक होने का जवाब नहीं जानता। –

+0

मैंने कभी ऐसा नहीं सुना है जो अन्यथा करता है। इसके अलावा, अगर ऐसा नहीं होता है, तो यह एक सी संकलक नहीं होगा, है ना? –

4

धारा 6.2.5.20 की आवश्यकता है कि सरणी आवंटित रूप से आवंटित हों। यह सरणी की सरणी के रूप में बहुत अधिक लागू होता है क्योंकि यह एक आयामी सरणी में होता है।

आपका मित्र बस गलत है। अगर आप की सीमा के भीतर रहने

जबकि बहुआयामी सरणियों हैं (शब्दार्थ, संभवतः नहीं शारीरिक रूप से) सन्निहित, सूचक arithmetics केवल परिभाषित किया गया है:

7

मुद्दे के अलावा अन्य जवाब में यह आवाज में थोड़ा और अधिक सूक्ष्म है आपके पॉइंटर मूल रूप से संदर्भित सरणी (वास्तव में, आप ऊपरी बाउंड के पीछे 1 तत्व जा सकते हैं, लेकिन केवल तभी यदि आप अव्यवस्था नहीं करते हैं)।

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

मुझे यकीन नहीं है कि क्या कंपाइलर ऑप्टिमाइज़ेशन उद्देश्यों के लिए इस जानकारी का उपयोग करते हैं, लेकिन सिद्धांत रूप में, वे कर सकते हैं। उदाहरण के लिए, यदि आप

float *p = &arr[2][3]; 
float *q = &arr[5][9]; 

तो p + x और q + y कभी नहीं उर्फ ​​चाहिए x और y के मूल्यों की परवाह किए बिना है।

+0

दरअसल; [इस सवाल] के उत्तरों को देखें (http://stackoverflow.com/questions/6290956/one-dimensional-access-to-a-multidimensional-array-well-defined-c) ... –

3

सी में अंतर्निहित बहु-आयामी सरणी इंडेक्स अनुवाद के माध्यम से लागू की जाती हैं।इसका मतलब यह है कि, उदाहरण के लिए, एक 3 डी सरणी T a[M][N][K] को 1 डी सर T a_impl[M * N * K] के रूप में कार्यान्वित किया गया है, बहु-आयामी पहुंच a[i][j][k] के साथ एकल-आयामी पहुंच a_impl[((i * N) + j) * K + k] में स्पष्ट रूप से अनुवाद किया जा रहा है। भाषा विनिर्देश स्पष्ट रूप से इस कार्यान्वयन का वर्णन नहीं करता है, हालांकि आवश्यकताओं को इसे बहुत अधिक सीधे जरूरी है।

इसे ध्यान में रखते हुए, यह स्पष्ट नहीं है कि आपका मित्र आपको संकलक द्वारा एक ही चीज़ के निहित कार्यान्वयन पर निर्भर होने के बजाय float arr[M * N] का उपयोग करने के लिए स्पष्ट रूप से क्यों बताएगा।

स्थिति है कि आप float arr[M * N] दृष्टिकोण पर विचार करने के लिए कर सकता है जब M और N दोनों रन-टाइम मूल्यों हैं और अपने संकलक चर लंबाई सरणियों का समर्थन नहीं करता (या आप किसी कारण से उन्हें का उपयोग नहीं करना चाहते हैं)। ऐसे मामलों में बहुआयामी सरणी के लिए अंतर्निहित समर्थन अब लागू नहीं होता है, क्योंकि यह संकलन-समय स्थिरांक होने वाले सभी आकारों (पहले को छोड़कर) पर निर्भर करता है। शायद यही आपके दोस्त को दिमाग में था।

+0

भले ही आपका कंपाइलर नहीं करता वीएलए का समर्थन नहीं करते हैं, आप अभी भी रनटाइम पर एक वास्तविक बहुआयामी सरणी आवंटित कर सकते हैं। इसका उपयोग करने के लिए यह केवल कुछ (सकल) वाक्यविन्यास जिमनास्टिक है। –

+0

@ करल नोरम: यदि कोई दूसरा, तीसरा और आगे आकार संकलित-समय स्थिरांक है तो कोई वास्तविक बहुआयामी सरणी आवंटित कर सकता है। (जैसा उपर्युक्त सूत्र द्वारा दिखाया गया है, पहला आकार 'एम' सूचकांक पुनर्मूल्यांकन में भाग नहीं लेता है)। यही कारण है कि मैंने कहा कि किसी को "मैन्युअल" कार्यान्वयन पर विचार करना होगा जब ** ** ** ** '** ** और **' एन' रन-टाइम मान हैं। – AnT

+0

राइट - गोचाचा। –

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