सी

2016-02-10 4 views
120

में * पीआरटी + = 1 और * पीआरटी ++ के बीच अंतर मैंने सी का अध्ययन करना शुरू किया, और पॉइंटर को फ़ंक्शन के पैरामीटर के रूप में पॉइंटर पास करने के बारे में एक उदाहरण करते समय, मुझे एक समस्या मिली।सी

यह मेरा नमूना कोड है:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int* allocateIntArray(int* ptr, int size){ 
    if (ptr != NULL){ 
     for (int i = 0; i < size; i++){ 
      ptr[i] = i; 
     } 
    } 
    return ptr; 
} 

void increasePointer(int** ptr){ 
    if (ptr != NULL){ 
     *ptr += 1; /* <----------------------------- This is line 16 */ 
    } 
} 

int main() 
{ 
    int* p1 = (int*)malloc(sizeof(int)* 10); 
    allocateIntArray(p1, 10); 

    for (int i = 0; i < 10; i++){ 
     printf("%d\n", p1[i]); 
    } 

    increasePointer(&p1); 
    printf("%d\n", *p1); 
    p1--; 
    free(p1); 
    fgets(string, sizeof(string), stdin); 
    return 0; 
} 

समस्या, लाइन 16 में तब होता है जब मैं *ptr++ करने के लिए *ptr+=1 संशोधित करते हैं। अपेक्षित परिणाम पूरे सरणी और संख्या 1 होना चाहिए, लेकिन जब मैं *ptr++ का उपयोग करता हूं तो परिणाम 0.

+=1 और ++ के बीच कोई भिन्नता है? मैंने सोचा कि दोनों ही वही हैं।

+2

ध्यान दें कि दिया गया कोड संकलित नहीं होगा क्योंकि आपने 'स्ट्रिंग' घोषित नहीं किया है। –

+6

अन्य नोट्स: 1) 'allocateIntArray' एक बुरा नाम है क्योंकि ऐसा लगता है कि आप फ़ंक्शन से सरणी 'malloc' करते हैं, लेकिन आप नहीं करते हैं। मैं इसके बजाय 'fillIntArray' का सुझाव देता हूं। 2) आप 'allocateIntArray' के वापसी मूल्य का उपयोग नहीं करते हैं। मेरा सुझाव है कि आप रिटर्न टाइप को 'शून्य' में बदल दें। 3) 'if (ptr! = NULL)' फ़ंक्शन में नहीं होना चाहिए 'वृद्धि सूचक' 'if (* ptr! = NULL)'? 4) 'मॉलोक' में कास्ट असफल है। ऊपर सौरव की टिप्पणी देखें। 5) यह: 'के लिए (int i = 0; i <10; i ++) {printf ("% d \ n ", p1 [i]); } 'और' printf ("% d \ n", * p1); पी 1 -; 'अगर (पी 1! = एनयूएलएल) 'में संलग्न होना चाहिए। 6) 'string.h' अप्रयुक्त है। –

+1

संबंधित: [++ सी में एक संदर्भित सूचक पर?] (Http://stackoverflow.com/questions/859770/on-a- संदर्भित- सूचक-in-c) –

उत्तर

281

अंतर ऑपरेटर प्राथमिकता के कारण है।

पोस्ट-वृद्धि ऑपरेटर ++ में डीरेंसेंस ऑपरेटर * की तुलना में अधिक प्राथमिकता है। तो *ptr++*(ptr++) के बराबर है। दूसरे शब्दों में, पोस्ट वृद्धि में सूचक को संशोधित किया जाता है, न कि यह क्या इंगित करता है।

असाइनमेंट ऑपरेटर +=, भिन्नता ऑपरेटर * की तुलना में कम पूर्वता है तो *ptr+=1(*ptr)+=1 के बराबर है। दूसरे शब्दों में, असाइनमेंट ऑपरेटर उस मान को संशोधित करता है जो पॉइंटर इंगित करता है, और पॉइंटर को स्वयं नहीं बदलता है। आप इस विषय पर अधिक जानकारी के लिए इस page जांच कर सकते हैं

बाद वेतन वृद्धि ++>* भिन्नता> काम +=

:

+3

शुरुआती लोगों के लिए, '* पी ++' और '* ++ पी' के बीच एक निमोनिक समानता है। उत्तरार्द्ध की ऑपरेटर प्राथमिकता स्पष्ट है, पूर्व में से एक है। –

21

अपने प्रश्न में शामिल 3 ऑपरेटरों के लिए प्राथमिकता का क्रम निम्नलिखित है।

अभिव्यक्ति को पार करते समय, कुछ पंक्तियों पर सूचीबद्ध एक ऑपरेटर को इसके नीचे एक पंक्ति पर सूचीबद्ध किसी भी ऑपरेटर की तुलना में अपने तर्कों के लिए कठिन (जैसे कि ब्रांड्स द्वारा) बाध्य किया जाएगा। उदाहरण के लिए, *p++ अभिव्यक्ति *(p++) के रूप में पार्स की गई है, और (*p)++ के रूप में नहीं है।

लंबी कहानी संक्षेप में, आदेश के बाद वेतन वृद्धि ऑपरेटर आप भिन्नता ऑपरेटर के लिए कोष्ठक जोड़ने की जरूरत का उपयोग कर के रूप में ++ से अधिक है कि आपरेशन पूर्वता देने के लिए इस असाइनमेंट *ptr+=1 व्यक्त करने के लिए इस (*ptr)++

+3

इंटेरेसिंगली, वर्तमान में यह एकमात्र उत्तर है जिसमें समाधान शामिल है ... (* पीआरटी) ++ – hyde

7

लेट्स कोष्ठक लागू order of operations

a + b/c 
a + (b/c) 

दिखाने के लिए की

के साथ फिर से इसे करते हैं
*ptr += 1 
(*ptr) += 1 

और फिर

*ptr++ 
*(ptr++) 
  • *ptr += 1 में साथ, हम अपने सूचक अंक को चर के मूल्य को बढ़ा देते।
  • *ptr++ में, हम हमारे पूरे बयान (कोड की पंक्ति) किया जाता है के बाद सूचक को बढ़ा देते हैं, और हमारे सूचक अंक चर के लिए एक संदर्भ लौट आते हैं।

    for(int i = 0; i < length; i++) 
    { 
        // Copy value from *src and store it in *dest 
        *dest++ = *src++; 
    
        // Keep in mind that the above is equivalent to 
        *(dest++) = *(src++); 
    } 
    

    यह एक और dest सरणी में एक src सरणी कॉपी करने के लिए इस्तेमाल एक आम तरीका है:

बाद आप की तरह काम करने के लिए अनुमति देता है।

+0

"और हमारे सूचक बिंदुओं के चर के संदर्भ को वापस लौटाएं।" सी संदर्भ नहीं है। –

+0

@ माइल्स रूट शायद इसे एक लवल्यू कहकर अधिक सटीक हो सकता है? लेकिन मुझे यकीन नहीं है कि इसे शब्दकोष जोड़ने के बिना कैसे रखा जाए। –

3

बहुत अच्छा सवाल है।

के & आर "सी प्रोग्रामिंग भाषा" "5.1 पॉइंटर्स और पता", हम इसके लिए उत्तर प्राप्त कर सकते हैं।

"एकल ऑपरेटरों * और & बाँध अधिक मज़बूती से अंकगणितीय ऑपरेटर"

*ptr += 1  //Increment what ptr points to. 

"की तरह एकल ऑपरेटरों * और ++ सहयोगी बाएं से दाएं।"

*ptr++  //Increment prt instead of what ptr point to. 

// यह * (पीआरटी ++) की तरह काम करता है।

सही तरीका है:

(*ptr)++  //This will work. 
+0

क्या आप कोड भाग को प्रारूपित कर सकते हैं? – manetsus

+0

यह पहली बार है जब मैं स्टैक ओवरफ़्लो पर टिप्पणी करता हूं। मैंने कोड के प्रारूप को अपडेट किया है। ^^ आपके सुझाव के लिए धन्यवाद। –

2

* ptr + = 1: बढ़ते क्रम में डेटा है कि करने के लिए अंक ptr। * पीआरटी ++: वृद्धि सूचक जो पॉइंटर पॉइंट के डेटा के बजाए अगली मेमोरी लोकेशन पर इंगित करता है।