यह संरचना
char **Data[70]={NULL};
संकेत दिए गए चार करने के लिए करने के लिए 70 संकेत की एक सरणी है। कंपाइलर इस सरणी के लिए 70 * sizeof(char**)
बाइट आवंटित करता है, जो 32-बिट पॉइंटर्स 280 बाइट मानते हैं।
यदि आप आंतरिक रूप से एक स्ट्रिंग के रूप में "पॉइंटर टू char" के बारे में सोचते हैं, जो सत्य नहीं है लेकिन यह काफी करीब है, तो यह तारों के लिए 70 पॉइंटर्स की एक सरणी है। कुछ ASCII आर्ट बनाने के लिए और बहाना है कि आप आवंटित और कुछ मूल्यों से जमा की है करने के लिए ....
Array of One or more
char ** char *
+---------+ +---------+
| 0 | --> | ptr | --> "Hello, world"
+---------+ +---------+
| 1 |
+---------+ +---------+
| 2 | ----> | ptr2 | --> "Goodbye, cruel world"
+---------+ +---------+
| 3 |
+---------+ +---------+
| 4 | ------> | ptr3[0] | --> "Message 0"
+---------+ +---------+
... | ptr3[1] | --> "Message 1"
+---------+ +---------+
| 69 | | ptr3[2] | --> "Message 2"
+---------+ +---------+
आप (त्रुटि जाँच malloc वापसी मूल्यों को छोड़ दिया) इस तरह के कोड के साथ ऊपर कर सकता है:
char **Data[70]={NULL};
char **ptr, **ptr2, **ptr3;
ptr = (char **) malloc(sizeof(char *));
*ptr = "Hello, world";
Data[0] = ptr;
ptr2 = (char **) malloc(sizeof(char *));
*ptr2 = "Goodbye, cruel world";
Data[2] = ptr2;
ptr3 = (char **) malloc(10 * sizeof(char *));
Data[4] = ptr3;
ptr3[0] = "Message 0";
ptr3[1] = "Message 1";
...
ptr3[9] = "Message 9";
printf("%s\n", *Data[0]);
printf("%s\n", Data[2][0]);
printf("%s\n", Data[4][0]);
printf("%s\n", Data[4][1]);
...
printf("%s\n", Data[4][9]);
इस बारे में सोचें: सरणी में प्रत्येक प्रविष्टि char **
है। प्रत्येक प्रविष्टि स्मृति में एक मनमाना स्थान को इंगित कर सकती है, कहा गया स्थान char *
है और इस प्रकार एक शून्य-समाप्त वर्ण सरणी उर्फ "स्ट्रिंग" को इंगित करने में सक्षम है।
नोट ध्यान से इस और क्या बीच भेद जब आप एक 2 डी सरणी का आवंटन आपको मिलेगा:
char *Data2[10][70]={NULL};
Data2
के आवंटन ऊपर आप char *
संकेत के एक 2-आयामी सरणी देता है, ने कहा कि 2-डी सरणी जा रहा है स्मृति के एक टुकड़े में आवंटित (10 * 70 * sizeof(char*)
बाइट्स, या 32-बिट पॉइंटर्स के साथ 2800 बाइट्स)। आपके पास char **
पॉइंटर्स को char **
पॉइंटर्स की एकल-आयामी सरणी के साथ स्मृति में मनमानी स्थानों पर असाइन करने की क्षमता नहीं है।
भी ध्यान रखें कि संकलक निम्नलिखित सरणी संदर्भ के लिए अलग-अलग कोड उत्पन्न होगा (Data
की घोषणाओं और Data2
ऊपर दिए गए):
Data[0][0]
Data2[0][0]
यहाँ एक और तरीका यह के बारे में सोचना है: कल्पना कीजिए कि आप कई है तारों के पॉइंटर्स के सरणी:
char *table0[] = { "Tree", "Bench", "Stream" };
char *table1[] = { "Cow", "Dog", "Cat" };
char *table2[] = { "Banana", "Carrot", "Broccoli" };
char **Data[3];
Data[0] = table0;
Data[1] = table1;
Data[2] = table2;
आपके पास "पॉइंटर टू चार्" के पॉइंटर्स की एक सरणी है। यदि अब आप data[1][1]
के मान को प्रिंट करते हैं, तो इस बारे में सोचें: आपको table1
सरणी में एक सूचक प्राप्त करता है। फिर मान table1[1]
"Dog"
के बराबर है।
आपके महान उत्तर को इस पालतू-पीवी-उत्तर से लापरवाही से जोड़ा गया है: http://stackoverflow.com/questions/423823/whats-your-favorite-programmer-ignorance-pet-peeve/484900#484900। चीयर्स :) –
इस तरह के एक अच्छे जवाब लिखने के लिए समय लेने के लिए धन्यवाद। यह बहुत साफ हो जाता है। जहां तक आपका पहला आरेख, आप कैसे जानते हैं कि सूचक एक पॉइंटर (जैसे पीआरटी 2) या पॉइंटर्स की एक सरणी को इंगित कर रहा है, जैसे कि ptr3 [0-2] क्या यह आरेख में दोनों हो सकता है? उदाहरण के लिए, आपका दूसरा चित्र सुसंगत है। धन्यवाद। –
यह जानने का कोई तरीका नहीं है कि वास्तव में, एक char ** सूचक बिंदु क्या है। यह किसी भी आकार के स्मृति क्षेत्र को इंगित कर सकता है। कोड को देखे बिना इसे सौंपा गया है, जानने का कोई तरीका नहीं है। – Eddie