2014-11-20 6 views
11

जब मैंने सी भाषा के बारे में किताबें पढ़ीं, तो दो स्तर के सूचक ने मुझे बहुत परेशान किया।char * s [] और char (* s) [] के बीच क्या अंतर है?

char s[5][5]; 
char *s[5]; 
char (*s)[5]; 

तो उनके बीच क्या अंतर है?

+6

http://cdecl.org/ रूप में ही हो, या 'cdecl' कार्यक्रम स्थापित हो जाएगा। –

+0

दूसरा उदाहरण 'char * s [5]; 'के रूप में अधिक स्पष्ट रूप से लिखा गया है। – aroth

उत्तर

8
  • पहले चार की 2 आयामी सरणी है
  • दूसरी सूचक की सरणी चार को चार की एक सरणी के लिए
  • तीसरे सूचक है
+0

यह भी उल्लेखनीय है कि 2-आयामी सरणी केवल सरणी की सरणी है। –

+1

या 5, 5 वर्ण सरणी ' –

16

सी में, यह बेहतर बाहर बात करने के लिए है घोषणा। फिर, यह सहज हो जाता है। इसके लिए, आप दाएं बाएं सम्मेलन का पालन करते हैं। यहाँ यह कैसे जाता है:

char *s[5]; 

कैसे आप यह बोल रहे हैं? इसके लिए आप चर नाम s के दाईं ओर शुरू करते हैं और फिर बाईं ओर जाते हैं। तो आप कहकर शुरू करते हैं कि "एस/ए" है, दाईं ओर, आप [] देखते हैं और आप कहते हैं कि "एक सरणी है ..."। और फिर आप बाईं ओर जाते हैं और * देखते हैं, और कहते हैं कि "पॉइंटर्स की एक सरणी है।" और यही वह है। यह 5 पॉइंटर्स की एक सरणी है। आप इस सरणी में विभिन्न पॉइंटर्स स्टोर कर सकते हैं।

अब एक दूसरे के लिए:

char (*s)[5]; 

आप उसी तरह शुरू करते हैं। "एस/ए" है, और फिर () देखें। () के भीतर कुछ भी s से बाहर कुछ भी के करीब है। तो *[] से अधिक निकटता से बंधे हैं। तो अब आप कहते हैं, "एक सूचक है ..." और अब आप कोष्ठक से बाहर निकलें और [] देखें। तो आप जारी रखते हैं, "एक सरणी के लिए एक सूचक है"। और यह वही है जो यह है। यह एक सूचक है, जो एक सरणी के पहले तत्व को इंगित करेगा।

अब एक ही तर्क का पालन करें और अनुमान लगाना क्या निम्नलिखित हो जाएगा कोशिश:

int (*callme)(int a, int b) 
int (*callme[10])(int a, int b) 

सुझाव, पिछले एक कार्यों के लिए देखने तालिकाएं बनाने के लिए इस्तेमाल किया जा सकता।

संपादित करें:

टिप्पणी में उल्लेख किया है, वहाँ भी शुरुआत में एक char है। मैंने कभी भी यह बोलने का आसान तरीका नहीं समझ पाया है, लेकिन आम तौर पर संदर्भ से स्पष्ट है। उदाहरण के लिए, पहले उदाहरण में, char सरणी के प्रकार को परिभाषित करता है, जबकि दूसरे उदाहरण में, यह सूचक को परिभाषित करता है। मैंने जो अभ्यास पोस्ट किए हैं, int कार्यों के वापसी मूल्यों के प्रकार को परिभाषित करता है। आम तौर पर इन तरह की परिभाषाओं के साथ, अनिर्धारित प्रकार के साथ बिल्कुल एक आइटम होगा। और यह है कि मैं कैसे पता लगाता हूं कि प्रकार कहां जाता है।

+0

की' सरणी 'आप' char' शामिल करना भूल गए; 'char * s [5]' किसी भी प्रकार के 5 "अलग पॉइंटर्स" की सरणी नहीं है, यह विशेष रूप से 5 पॉइंटर्स * 'char' * की सरणी है। –

+0

यह सच है। मुझे इसका उल्लेख करना चाहिए था। – ssm

+0

मुझे नहीं लगता कि यह कहने में पूरी तरह सही है कि '()' की प्राथमिकता है। शायद आप का मतलब है कि कोष्ठक की उपस्थिति जटिल घोषणाकर्ताओं के * बाध्यकारी * को बदल सकती है। –

3

जबकि declaration कवर किया गया था, शायद उपयोग में मतभेद भी बताया जाना चाहिए:

char s[5][5]; - आबंटित स्मृति के एक क्षेत्र को

  • s अंक (ढेर वैश्विक है, ढेर यदि स्थानीय),
  • आप s[0][0] पर 25 char मानों को सुरक्षित रूप से लिख सकते हैं .. s[4][4] (या s[0] पर .. s[24]),
  • sizeof(s) == 25.

char *s[5]; -

  • s आबंटित स्मृति के एक क्षेत्र को अंक (यदि वैश्विक ढेर, स्थानीय अगर ढेर),
  • आप सुरक्षित रूप से करने के लिए लिख सकते हैं 5 सूचक मूल्य s[0] पर .. s[4],
  • sizeof(s) == 40 (*)।

char (*s)[5]; - यह केवल इस बिंदु पर एक गैर-आरंभिकृत सूचक है,

  • आप सुरक्षित रूप से &s पर एक सूचक मूल्य लिख सकते हैं
  • -

    • s किसी भी आबंटित स्मृति को नहीं बिंदु करता है
    • sizeof(s) == 8 (*)।

    (*) नोट: 64-बिट आर्किटेक्चर मानते हुए।

    3

    1.char s [5] [5];
    यहां 5 पंक्तियों और 5 कॉलम के साथ दो आयामी सरणी है। इस 5 पंक्तियों और 5 कॉलम में आप टाइप कैरेक्टर के तत्व को कैसे सहेज लेंगे।

    2.char * s [5]; एस 5 तत्वों वाला एक आयामी सरणी है प्रत्येक तत्व चरित्र के लिए प्रकार सूचक है।

    3.char (* s) [5]; एस यहां एक पॉइंटर है जो सरणी नहीं है। एस वर्णों की एक सरणी को इंगित करता है। उदाहरण के लिए।

    char arr[5][5]; char(*s)[5]; s = arr;

    रों [0] [0] आगमन की सरणी [0] [0]

    +0

    'char (* s) [5] 'सिर्फ एक सूचक है? क्या 'char * s',' char (* s) [5] 'और' char (* s) [10] 'के बीच कुछ अंतर है? – storen

    +0

    @ स्टोरेन हां चार (* एस) [5] सिर्फ एक सूचक है। लेकिन यह चार की एक सरणी के लिए एक सूचक है। उदाहरण के लिए: 1. 'चार (* एस) [5]; चार एआर [2] [5]; एस = एआर; 'इस में 5 तत्वों की एक सरणी को इंगित कर रहा है जो एआर की पहली पंक्ति है। यदि आप s ++ करते हैं तो एआर की दूसरी पंक्ति में इंगित करता है। 2. 'चार * एस; चार एआर [5]; एस = एआर; यहां सरणी के पहले तत्व को इंगित किया गया है जो चरित्र है। यदि आप s ++ करते हैं तो यह अगले वर्ण ' – dido

    +0

    पर इंगित करता है लेकिन मैं जानना चाहता हूं कि संकलक कैसे जानता है कि इस सूचक का प्रकार int है, दूसरा char है? जब हम 'int * a' प्रकार को परिभाषित करते हैं, तो क्या संकलक न केवल' ए' मान को संग्रहीत करता है, बल्कि 'ए' के प्रकार को भी संग्रहीत करता है, इसलिए इसमें कुछ अतिरिक्त मेमोरी व्यय हो सकता है? – storen

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