2010-08-17 9 views
7

मेरे पास निम्न प्रोग्राम है। हालांकि, मुझे समझ में नहीं आ रहा है कि मुझे सरणी का पता क्यों पारित करना है। जब वे दोनों एक ही पते पर इशारा करते हैं। Int की सरणी के पहले तत्व का पता कौन सा है।मैं सीधे सी में पॉइंटर को सरणी क्यों नहीं दे सकता?

मैं एक चेतावनी मिलती है जब मैं कोशिश करते हैं और इस "असंगत सूचक प्रकार से काम" करते हैं:

ptr = var; 

पूरा स्रोत कोड:

void print_values(int (*ptr)[5]) 
{ 
    size_t i = 0; 
    for(i = 0; i < 5; i++) { 
     printf("%d: [ %d ]\n", i, (*ptr)[i]); 
    } 
} 

int main(void) 
{ 
    /* declare a pointer to an array integers */ 
    int (*ptr)[5] = NULL; 
    /* array of integers */ 
    int var[] = {1, 2, 3, 4, 5}; 
    /* assign the address of where the array is pointing to (first element) */ 
    ptr = &var; 
    /* Both are pointing to the exact same address */ 
    printf("var [ %p ]\n",(void*)var); 
    printf("&var [ %p ]\n", (void*)&var); 

    print_values(ptr); 
    return 0; 
} 

मैं gcc 4.4.4 c89 -Wall -Wextra -O0

+0

मैंने आपके शीर्षक को फिर से शुरू करने का प्रयास किया, क्योंकि यह अर्थहीन था। कृपया, सत्यापित करें कि मैंने आपकी समस्या का सही ढंग से चयन किया है या नहीं। –

+0

मुझे लगता है कि आपका शीर्षक मेरी तुलना में बेहतर लगता है। धन्यवाद। – ant2009

+0

आप कोड स्निपेट ठीक संकलित करता है। क्या आपका मतलब है कि अगर आप मुख्य रूप से 'ptr = var' जोड़ते हैं तो आपको एक त्रुटि मिलेगी? –

उत्तर

17

यह पूरी तरह से एक प्रकार का मुद्दा है।

अधिकांश अभिव्यक्ति में सरणी के प्रारंभिक तत्व के लिए एक सूचक के लिए एक संकेतक (जैसे var) decays का नाम संदर्भित करता है, सरणी के लिए सूचक नहीं। [नोट: यह मतलब यह नहीं है कि कि var एक सूचक है - यह बहुत ज्यादा नहीं एक सूचक है -। यह सिर्फ सबसे भाव में सरणी के पहले तत्व के लिए सूचक की तरह बर्ताव करता है]

यह साधन एक अभिव्यक्ति में var आमतौर पर int पर सूचक के लिए क्षय होता है, int की सरणी के लिए सूचक नहीं।

ऑपरेटर के पते के संचालन के रूप में (&) एक संदर्भ है जहां यह क्षय नियम लागू नहीं होता है (दूसरा sizeof ऑपरेटर के संचालन के रूप में होता है)। इस मामले में &var का प्रकार सीधे var के प्रकार से लिया गया है, इसलिए प्रकार 5 int की सरणी के लिए सूचक है।

हां, पॉइंटर्स के पास एक ही पता मूल्य है (एक सरणी का पता पहला तत्व सरणी का पता है), लेकिन उनके पास अलग-अलग प्रकार हैं (int* बनाम int(*)[5]) इसलिए असाइनमेंट में संगत नहीं हैं।

आईएसओ/आईईसी 9899: 1999 6.3.2.1/4:

जब यह sizeof ऑपरेटर या एकल & ऑपरेटर के संकार्य है, या एक स्ट्रिंग शाब्दिक एक सरणी प्रारंभ करने में प्रयोग किया जाता है के अलावा, एक अभिव्यक्ति जिसमें "प्रकार" प्रकार का प्रकार है "टाइप करने के लिए सूचक" प्रकार की अभिव्यक्ति में परिवर्तित किया गया है जो कि सरणी ऑब्जेक्ट के प्रारंभिक तत्व को इंगित करता है और एक अंतराल नहीं है। ...

+0

मैंने सोचा कि एक समारोह में बुलाए जाने पर सरणी केवल पॉइंटर्स में क्षय हो जाती है। तो अभिव्यक्ति में। int arr [5] = {1,2,3,4,5}; int * ptr = arr; जब पॉइंटर को सौंपा गया तो धमनी एक सूचक में क्षीण हो जाएगी? – ant2009

+0

@robUK: यह केवल फ़ंक्शन कॉल नहीं है, यह सबसे अभिव्यक्ति संदर्भ है जहां क्षय होता है। सरणी decays जब एक सूचक प्रारंभ करने के लिए प्रयोग किया जाता है; एक सूचक को 'int' में प्रारंभ करने के लिए पॉइंटर मान की आवश्यकता होती है, न कि' int' की सरणी। –

3

साथ कोड संकलन var स्वयं एक (*int) है जो आपके सरणी में पहले तत्व को इंगित करता है। सी में पॉइंटर्स और सरणी बेहद समान हैं। int (*ptr)[5] = NULL; से int* ptr = NULL; और ptr = &var; से ptr = var;

1

मैं क्या कहता हूं, आप एक सूचक है कि एक सरणी सूचक ((*ptr)[5]) की ओर इशारा करने के लिए एक सरणी सूचक (var) बताए जाते हैं कर सकते हैं ताकि तुम क्यों कि चेतावनी मिलती है से।

इसके बजाय, एक दृढ़ता से टाइप किया भाषा का प्रयोग

int *ptr = NULL; 
4

सी है की कोशिश करो।जब कोई फ़ंक्शन int * प्रकार के पैरामीटर की अपेक्षा करता है, तो आपको int * प्रकार का तर्क पारित करना होगा। double * नहीं, char * नहीं, लेकिन int *। भले ही double * या char * में वास्तविक संख्यात्मक पता "वही" जैसा है जिसे आप पास करना चाहते हैं, फिर भी यह कुछ भी नहीं बदलेगा - आपको अभी भी int * पास करना होगा। भाषा आपको गलत प्रकार के मूल्य को पार करने से रोकती है।

यह आपके मामले में बिल्कुल होता है। फ़ंक्शन int (*)[5] प्रकार का पैरामीटर लेता है। इसका मतलब है कि आपको उस प्रकार के तर्क को पारित करना होगा। इसके बजाय int * पास करने की अनुमति नहीं है। चाहे पता वही है, कोई फर्क नहीं पड़ता।

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