2010-12-17 18 views
13

हम दो आयामी सरणी का प्रतिनिधित्व करने के लिए डबल पॉइंटर का उपयोग क्यों नहीं कर सकते?हम दो आयामी सरणी का प्रतिनिधित्व करने के लिए डबल पॉइंटर का उपयोग क्यों नहीं कर सकते?

arr[2][5] = {"hello","hai"}; 
**ptr = arr; 

यहां इस उदाहरण में डबल पॉइंटर (** पीटीआर) क्यों काम नहीं करता है?

+0

आपने किस प्रश्न को संकलित किया है जो आपके प्रश्न में कोड के समान है? –

+1

बहुआयामी सरणी से दूर भागें (शायद छोटे लोगों को छोड़कर)। –

+2

@Alexandre C. बहुआयामी सरणी सरल, उपयोगी और कुशल हैं। आप उनसे दूर भागना क्यों चाहेंगे? – Shahbaz

उत्तर

8

होने सूचक-टू-सूचक का मतलब है प्रत्येक पंक्ति (या स्तंभ है, तो आप इसके बारे में लगता है कि जिस तरह से पसंद करते हैं) अन्य पंक्तियों/स्तंभों से एक अलग लंबाई हो सकता है।

आप प्रारंभ तत्व करने के लिए सिर्फ एक सूचक है, और एक पूर्णांक है कि प्रति पंक्ति/स्तंभ तत्वों की संख्या को निर्दिष्ट करके 2D सरणी का प्रतिनिधित्व कर सकते हैं:

void matrix_set(double *first, size_t row_size, size_t x, size_t y, double value) 
{ 
    first[y * row_size + x] = value; 
} 
+1

मेरा सवाल यह है कि यह क्यों और कैसे काम कर रहा है। – Thangaraj

7

सी में, एक दो आयामी सरणी है सरणी के सरणी

आप एक सूचक करने वाली सरणी यह ​​उल्लेख करने के लिए, नहीं एक डबल सूचक की जरूरत है:

char array[2][6] = {"hello", "hai"}; 
char (*p)[6] = array; 
//char **x = array; // doesn't compile. 

एक डबल सूचक के लिए "2-आयामी डेटा" का उल्लेख करने के, यह पहली का उल्लेख करना चाहिए पॉइंटर्स की सरणी का तत्व। लेकिन सी (सरणी की सरणी) में एक 2-आयामी सरणी पॉइंटर्स की सरणी के समान नहीं है, और यदि आप केवल 2-डी सरणी को परिभाषित करते हैं, तो पॉइंटर्स की कोई भी संबंधित सरणी मौजूद नहीं है।

दोनों के बीच एकमात्र समानता [][] सिंटैक्स डेटा तक पहुंचने के लिए उपयोग की जाती है: डेटा स्वयं को अलग-अलग संरचित किया जाता है। कानूनी कोड बारे में बात करके

1

आइए शुरू। आपने जो लिखा है (प्रत्येक घोषणा के सामने एक char मानते हैं) संकलित नहीं होगा, कई कारणों से: आपके पास बहुत से प्रारंभिक हैं (एआर [0] के लिए छह char, और इसका आकार 5 है), और निश्चित रूप से, चार ** पी में चार एआर [2] [5] के साथ संगत प्रकार नहीं है। उन समस्याओं के लिए सुधार, हमें मिलता है:

char arr[2][6] = { "hello", "hai" }; 
char (*p)[6] = arr; 

बिना किसी डबल पॉइंटर के।

char* pc = *arr; 

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

सी ++ दो आयामी सरणियों जरूरत नहीं है। उपरोक्त पहली परिभाषा चार के सरणी [2] या सरणी [6] को परिभाषित करती है। पॉइंटर रूपांतरण परिणामों के लिए implicite सरणी सूचक के सूचक [6] में सूचक में परिणाम। इसके बाद, निश्चित रूप से, सूचक रूपांतरण के लिए कोई सरणी नहीं है, क्योंकि अब आपके पास कोई सरणी नहीं है।

3

आदेश एक वस्तु "की तरह दिखता है" कि प्राप्त करने के लिए प्रत्येक पंक्ति के संकेत की एक सरणी बनाने चर आकार की एक बहुआयामी सरणी वाक्यात्मक चीनी की खातिर एक महंगी डिजाइन विकल्प है। ऐसा मत करो

एक चर आकार बहुआयामी सरणी करने के लिए सही तरीका है कुछ की तरह:

if (w > SIZE_MAX/sizeof *m/h) goto error; 
m = malloc(w * h * sizeof *m); 
if (!m) goto error; 
... 
m[y*w+x] = foo; 

आप इसे ताकि आप m[y][x] लिख सकते हैं, आप एक अलग भाषा का प्रयोग किया जाना चाहिए "सुंदर लग रही हो" चाहते हैं, शायद सी ++।

+3

आप कंपाइलर को ऑफ़सेट गणना करने के लिए चर-लंबाई सरणी का उपयोग कर सकते हैं: 'int (* foo) [cols] = malloc (sizeof * foo * पंक्तियां) 'परिचित' foo [i] का उपयोग करना संभव बनाता है [जे] 'वाक्यविन्यास; – Christoph

+0

@ क्रिस्टोफ: दरअसल, यदि आपके पास सी 99 कंपाइलर है, तो यह काम करता है। आपको सरणी को पारित करने वाले किसी फ़ंक्शन कॉल पर आयामों को ठीक से पारित करने की व्यवस्था करने की आवश्यकता है, हालांकि। –

33

मैं आकर्षित करने के लिए प्रयास करने के लिए जा रहा हूँ कैसे

int array[10][6]; 

और

int **array2 = new int *[10]; 
for (int i = 0; i < 10; ++i) 
    array2[i] = new int[6] 

नज़र स्मृति में और कैसे वे अलग हैं (और है कि वे एक दूसरे से ढाला नहीं जा सकता की तरह)

array लगता है:

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
| | | | | | | | | | | | | ..............| | | (10*6 elements of type int) 
- - - - - - - - - - - - - - - - - - - - - - 
< first row >< second row> ... 

array2 लगता है:

_ _ _ _ _ _ _ _ _ _ 
| | | | | | | | | | | (10 elements of type int *) 
- - - - - - - - - - 
| |  ....  |  _ _ _ _ _ _ 
| |    \-->| | | | | | | (6 elements of type int) 
| |      - - - - - - 
| | 
| |  _ _ _ _ _ _ 
| \ -->| | | | | | | (6 elements of type int) 
|  - - - - - - 
| 
| 
|  _ _ _ _ _ _ 
    \ -->| | | | | | | (6 elements of type int) 
     - - - - - - 

जब आप कहते हैं कि array[x][y], इसे में *(((int *)array)+x*6+y)

जबकि तब्दील हो, जब आप कहते हैं array2[x][y], यह *(*(array2+x)+y)

यही है, एक स्थिर 2 डी सरणी में है में तब्दील वास्तव में एक पंक्ति में रखी पंक्तियों के साथ एक 1 डी सरणी। सूचकांक की गणना row * number_of_columns_in_one_row + column सूत्र द्वारा की जाती है।

एक गतिशील 2 डी सरणी, हालांकि पॉइंटर्स की केवल 1 डी सरणी है। प्रत्येक पॉइंटर को गतिशील रूप से आवंटित किया जाता है ताकि दूसरे 1 डी सरणी को इंगित किया जा सके। सच में, वह सूचक कुछ भी हो सकता है। NULL हो सकता है, या एक परिवर्तक को इंगित कर सकता है, या किसी अन्य सरणी को इंगित कर सकता है। और उनमें से प्रत्येक पॉइंटर्स अलग-अलग सेट होते हैं, इसलिए उनके पास अलग-अलग स्वरूप हो सकते हैं।

आप array का सूचक कहीं पारित करने के लिए की जरूरत है, तो आप इसे int ** में ढाला नहीं जा सकता है (कल्पना क्या होगा array की कोशिकाओं के int मूल्यों संकेत के रूप में व्याख्या और dereferenced कर रहे हैं -।> बैम विभाजन गलती!)। हालांकि आप array के int [6] एस के 1 डी सरणी के रूप में सोच सकते हैं; यह int [6] टाइप के साथ तत्वों की एक 1 डी सरणी है। इसे लिखने के लिए, आप कहते हैं कि

int (*p)[6] = array; 
संबंधित मुद्दे