2011-11-12 20 views
23

मैं कश्मीर & आर (उदा। 5-9) और मैं में एक अभ्यास पर काम कर रहा हूँ की सरणी के लिए सूचक के लिए अदिश प्रारंभकर्ता के तत्वोंअतिरिक्त ints

static char daytab[2][13] = { 
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 
}; 
के मूल कार्यक्रम के 2 डी सरणी परिवर्तित करने के लिए कोशिश कर रहा था जैसे

static char (*daytab)[13] = { 
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 
}; 

लेकिन संकलक प्रिंट 13 ints की एक सरणी की ओर इशारा का उपयोग करते हुए

चेतावनी: अदिश प्रारंभकर्ता में अतिरिक्त तत्वों।

Googling मदद नहीं था और यहां तक ​​कि कश्मीर & आर लिखते हैं जब एक समारोह के लिए सरणी गुजर,

myFunction(int daytab[2][13]) {...} 

myFunction(int (*daytab)[13]) {...} 

उत्तर

25

के रूप में ही दो केवल आंशिक रूप से बराबर हो रहा है। अंतर किया जा रहा है कि:

static char daytab[2][13] = { 
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 
}; 

एक दो आयामी सरणी है, जो एक तरफ सरणी के लिए जगह की स्थापना और कि daytab संदर्भ स्मृति सुनिश्चित करना शामिल है की घोषणा की। हालांकि:

static char (*daytab)[13] = { 
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 
}; 

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

तो यदि आप इस तरह के प्रारंभिक कार्य करना चाहते हैं, तो पहले संस्करण का उपयोग करें - यह उसी पॉइंटर प्रकार को क्षय करता है जिसे आप स्पष्ट रूप से दूसरे संस्करण में घोषित करते हैं, ताकि आप इसे उसी तरह उपयोग कर सकें। सरणी पॉइंटर के साथ दूसरा संस्करण आवश्यक है जब आप गतिशील रूप से सरणी आवंटित करना चाहते हैं या किसी अन्य सरणी का संदर्भ प्राप्त करना चाहते हैं जो पहले से मौजूद है।

तो तुम यह कर सकते हैं:

static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; 
static char (*ptr)[3] = NULL; 

ptr = arr; 

... और फिर ptr और arr का उपयोग दूसरे के स्थान पर। या यह:

static char (*ptr)[3] = NULL; 

ptr = malloc(2 * sizeof(*ptr)); 

... एक गतिशील आवंटित 2-आयामी सरणी (नहीं -1 डी सरणियों की ओर इशारा की एक सरणी है, लेकिन कोई वास्तविक 2 डी सरणी) प्राप्त करने के लिए। बेशक, यह उस मामले में शुरू नहीं हुआ है।

दो भिन्नताओं के "समकक्ष" का अर्थ केवल 2 डी सरणी है, जब यह अपने पहले तत्व में सूचक के लिए क्षय हो जाता है, तो दूसरी भिन्नता में घोषित सूचक के प्रकार का क्षय होता है। एक बार पॉइंटर संस्करण वास्तव में एक सरणी पर इंगित किया जाता है, दोनों बराबर हैं। लेकिन 2 डी सरणी संस्करण सरणी के लिए मेमोरी सेट करता है, जहां पॉइंटर घोषणा नहीं होती है ... और पॉइंटर को एक नया मान (एक अलग सरणी पर इंगित किया जा सकता है) जहां 2 डी सर चर चर नहीं कर सकता है।

C99 में आप यह कर सकते हैं, हालांकि (यदि नहीं static कम से कम):

char (*daytab)[13] = (char [][13]){ 
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, 
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 
}; 
+0

ढेर अंतरिक्ष? यदि यह स्थिर है तो यह डेटा अनुभाग में जाता है। –

+0

@ ब्रायन गॉर्डन सुधार हुआ ... मैं उस हिस्से को टाइप करते समय "स्थिर" के बारे में भूल गया (मुझे लगता है ... यह बहुत समय पहले था)। – Dmitri

+0

और उसके बाद पॉइंटर को इस '(* (daytab + leap)) तक पहुंचा जा सकता है [i] '(अभ्यास के संबंध में) – Vladimir

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