2011-09-08 17 views
18
#include<stdio.h> 
main() 
{ int x[3][5]={{1,2,10,4,5},{6,7,1,9,10},{11,12,13,14,15}}; 


printf("%d\n",x); 
printf("%d\n",*x); } 

यहां पहला प्रिंटफ पहले तत्व के पते को प्रिंट करेगा। तो क्यों दूसरा printf पता x i.e पर पहला मान मुद्रित करता है। मूल्य मुद्रित करने के लिए मुझे ** x लिखना होगा।सी में पॉइंटर्स में अस्पष्टता की व्याख्या करें?

+0

क्या आप वाकई पहले printf मूल्य के बजाय पता प्रिंट होगा कर रहे हैं ?? –

उत्तर

26

पॉइंटर्स के लिए, x[0]*x जैसा ही है। यह इस प्रकार से आता है कि *x[0]**x जैसा ही है।

*x[0] में:

x एक int[3][5], जो जब अभिव्यक्ति में प्रयोग किया जाता int(*)[5] में परिवर्तित हो जाता है। तो एक्स [0] प्रकार int[5] (पहली 5-तत्व "पंक्ति") का अंतराल है, जो एक बार फिर int* में परिवर्तित हो जाता है, और इसके पहले तत्व को संदर्भित किया जाता है।

*x, उसी तर्ज पर मूल्यांकन किया जाता है को छोड़कर पहले भिन्नता तारांकित (के रूप में अनुक्रमण के खिलाफ), और कोई दूसरा भिन्नता है के साथ किया जाता है, तो हम प्रकार int[5] की lvalue, जो printf को पारित कर दिया है के साथ खत्म अपने पहले तत्व के लिए एक सूचक के रूप में।

+0

हाँ, लेकिन जब मैं "x" प्रिंट करता हूं तो मुझे पता मिलता है, इसलिए जब मैं ऑपरेशन करता हूं * x मुझे उस पते पर संग्रहीत मान प्राप्त करना चाहिए ... – dejavu

+0

हां और नहीं। आपको वास्तव में पते पर संग्रहीत मूल्य मिलता है, यह "प्रकार का अंतराल" int [5] '" मैं बात कर रहा था। हालांकि, Arrays सी में प्रथम श्रेणी नहीं हैं, वे अपने पहले तत्व के लिए पॉइंटर्स के रूप में कार्य करने के लिए पारित कर रहे हैं। तो 'printf' को पॉइंटर को 5 के पहले 'int' में मिलता है, जिसमें' x' के पहले तत्व के पते के समान पता होता है। IOW, '(शून्य *) x == (शून्य *) * x' और यही वह है जो आप देखते हैं। – jpalecek

+0

मैंने सवाल संपादित किया .. यह मेरा संदेह था ... वह गलत छाप था .. – dejavu

-1

पॉइंटर्स की एक सरणी के रूप में 2-डी सरणी के बारे में सोचें, जिसमें सरणी में प्रत्येक तत्व किसी अन्य सरणी में पहले तत्व को इंगित करता है। जब आप x को अव्यवस्थित करते हैं, तो आपको उस मान को मिलता है जो x द्वारा इंगित स्मृति स्थान में होता है ... int के पॉइंटर int एस की एक सरणी में। जब आप उस सूचक को अव्यवस्थित करते हैं, तो आपको पहला तत्व मिल जाएगा।

+3

यह सही नहीं है। आप निश्चित रूप से पॉइंटर्स की एक सरणी करके एक प्रभावी 2-डी जंजीर सरणी कर सकते हैं, लेकिन गुणा द्वारा किए गए डीरफ्रेंसिंग के साथ वास्तविक भंडारण क्रमशः पंक्ति-दर-पंक्ति है। – Yuliy

+0

@ यूलिय: मैं समझता हूं कि यह लागू नहीं किया गया है, लेकिन यह समझने का एक आसान तरीका है कि आपको दो बार अस्वीकार करने की आवश्यकता क्यों है। – Daniel

+1

@ डैनियल: यूलिया का मुद्दा खड़ा है। इस बारे में सी न्यूबीज के बीच पहले से ही काफी भ्रम है, और पहले से ही बहुत से लोग "दो आयामी सरणी" को पॉइंटर्स की सरणी के रूप में आवंटित करने की कोशिश कर रहे हैं, कि इस गलतफहमी को आगे बढ़ाने का कोई भी जोखिम टाला जाना चाहिए। –

4

Arrays, जब कार्यों के लिए तर्क के रूप में उपयोग किया जाता है, तो सरणी के पहले तत्व को पॉइंटर्स में क्षय हो जाता है। ऐसा कहा जा रहा है कि x क्षय में ऑब्जेक्ट का प्रकार पहले उप-सरणी का सूचक है, जो int की सरणी के लिए सूचक है, या मूल रूप से int (*)[5] है। जब आप printf("%d\n",*x) पर कॉल करते हैं, तो आप printf पर एक पूर्णांक मान नहीं खिला रहे हैं, बल्कि x के पहले उप-सरणी के लिए एक सूचक हैं। चूंकि वह उप-सरणी पहले उप-सरणी के तत्व में पॉइंटर को क्षीण कर देगी, इसलिए आप **x को बाद में पॉइंटर को अस्वीकार करने और x के पहले उप-सरणी के पहले तत्व पर पहुंच सकते हैं। यह प्रभावी रूप से *x[0] जैसा ही है, जो ऑपरेटर प्राथमिकता x की पहली उप-सरणी में इंडेक्स करेगा, और उसके बाद पॉइंटर को पहले उप-सरणी के तत्व को पूर्ववत करें कि पहले उप-सरणी क्षय हो जाएगी।

0

*x के प्रकार के कारण '5 इंच की सरणी के लिए सूचक' है। तो, आप पहले तत्व

पी एस प्राप्त करने के लिए एक और भिन्नता की जरूरत है:

#include <typeinfo> 
#include <iostream> 

typedef int arr[5]; // can't compile if put arr[4] here 
void foo(arr& x) 
{ 
} 

int main() 
{ 
    int x[3][5]={{1,2,10,4,5},{6,7,1,9,10},{11,12,13,14,15}}; 

    std::cout << typeid(*x).name() << std::endl;// output: int [5] 

    foo(x[0]); 
    return 0; 
} 

+0

'* x' का प्रकार" सूचक 'int' "(' int * ') है। यह अभिव्यक्ति में एक सूचक के लिए सरणी प्रकार क्षय के बाद, 'x' स्वयं है, जिसने "5' int की सरणी के लिए सूचक" टाइप किया है। –

+0

एआरएम, '* x' में" 5 इंच की सरणी "टाइप है, इसलिए मैं थोड़ा गलत था। अधिकांश संदर्भों में, "intter के लिए सूचक" टाइप करने का यह क्षय। यह निश्चित रूप से किसी भी व्याख्या में "5 इंच की सरणी के लिए सूचक" प्रकार नहीं है। –

+0

हां, मैंने अपना मूल संदेश बदल दिया और कुछ 'सबूत' जोड़ा। – qehgt

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