पॉइंटर एड्रेस और पॉइंटर का मान कैसे बढ़ाया जाए?


96

मान लो की,

int *p;
int a = 100;
p = &a;

निम्नलिखित कोड वास्तव में क्या करेगा और कैसे करेगा?

p++;
++p;
++*p;
++(*p);
++*(p);
*p++;
(*p)++;
*(p)++;
*++p;
*(++p);

मुझे पता है, यह कोडिंग के मामले में एक तरह से गड़बड़ है, लेकिन मैं जानना चाहता हूं कि जब हम इस तरह से कोड करेंगे तो वास्तव में क्या होगा।

नोट: मान लें कि इसका पता a=5120300, यह सूचक में संग्रहीत है pजिसका पता है 3560200। अब, p & aप्रत्येक कथन के निष्पादन के बाद क्या मूल्य होगा ?


3
तुम सिर्फ डिबगर में इसे क्यों नहीं चलाते?
एंडर्सके

24
अच्छा .. क्यों नहीं बस इसे आज़माएँ और देखें? printf% p
ब्रायन रोच

यदि आप व्यवहार के बारे में उत्सुक हैं, तो बस इसके साथ खेलें। बस एक साधारण सी प्रोग्राम लिखें जो इन सभी उपयोग के मामलों से गुजरता है और देखें कि क्या यह आपके लिए समझ में आता है।
सायरस

@AndersK। शायद ओपी को अपरिभाषित व्यवहार की उम्मीद है? ...या शायद नहीं।
मतीन उलहाक

जवाबों:


174

सबसे पहले, ++ ऑपरेटर * ऑपरेटर पर पूर्वता लेता है, और () ऑपरेटर अन्य चीजों पर पूर्वता लेता है।

दूसरा, ++ नंबर ऑपरेटर नंबर ++ ऑपरेटर के समान है यदि आप उन्हें कुछ भी नहीं दे रहे हैं। अंतर संख्या ++ रिटर्न संख्या और उसके बाद वेतन वृद्धि संख्या, और ++ संख्या वृद्धि पहले है और फिर इसे वापस लौटाता है।

तीसरा, एक पॉइंटर के मूल्य को बढ़ाकर, आप इसे अपनी सामग्री के आकार से बढ़ा रहे हैं, कि आप इसे बढ़ा रहे हैं जैसे कि आप किसी सरणी में पुनरावृत्ति कर रहे थे।

तो, इसे पूरा करने के लिए:

ptr++;    // Pointer moves to the next int position (as if it was an array)
++ptr;    // Pointer moves to the next int position (as if it was an array)
++*ptr;   // The value of ptr is incremented
++(*ptr); // The value of ptr is incremented
++*(ptr); // The value of ptr is incremented
*ptr++;   // Pointer moves to the next int position (as if it was an array). But returns the old content
(*ptr)++; // The value of ptr is incremented
*(ptr)++; // Pointer moves to the next int position (as if it was an array). But returns the old content
*++ptr;   // Pointer moves to the next int position, and then get's accessed, with your code, segfault
*(++ptr); // Pointer moves to the next int position, and then get's accessed, with your code, segfault

जैसा कि यहां बहुत सारे मामले हैं, मैंने कुछ गलती की होगी, अगर मैं गलत हूं तो कृपया मुझे सुधारें।

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

इसलिए मैं गलत था, मैंने जो लिखा है, उससे कहीं अधिक जटिल है, इसे यहां देखें: http://en.cppreference.com/w/cpp/language/operator_precedence


6
* ptr ++, मान वृद्धि नहीं है, सूचक है। इन यूनिरी ऑपरेटर्स की एक ही मिसाल है लेकिन इनका मूल्यांकन राइट-टू-लेफ्ट किया जाता है। कोड का अर्थ है "जहां से ptr बिंदुओं पर सामग्री ले जाएं, उसके बाद वेतन वृद्धि ptr"। यह बहुत ही सामान्य सी कोड है (और हाँ, काफी भ्रामक)। कृपया इसे सुधारें और मैं नीचे को हटा दूंगा। * (Ptr) ++ के लिए समान, कोष्ठक कुछ नहीं करता है।
लुंडिन

बहुत बहुत धन्यवाद लंडिन, क्या मुझे कुछ और याद आया?
felipemaia

@ लुंडिन हाय, क्या अब ऊपर का जवाब सही है? धन्यवाद।
उन्हेलिग

4
@Unheilig पहला वाक्य अभी भी पूरी तरह से गलत है, पोस्टफिक्स ++ ने यूनरी * पर पूर्ववर्तीता ली है जिसमें प्रीफिक्स ++ के समान ही पूर्वता है। इसके अलावा, यह ठीक लगता है।
लंडिन

4
@felipemaia क्या आप सुनिश्चित हैं कि यह सेगफ़ॉल्ट होगा? शायद इसका सिर्फ अपरिभाषित व्यवहार?
jotik

13

कार्यक्रम की जाँच की और परिणाम इस प्रकार हैं,

p++;    // use it then move to next int position
++p;    // move to next int and then use it
++*p;   // increments the value by 1 then use it 
++(*p); // increments the value by 1 then use it
++*(p); // increments the value by 1 then use it
*p++;   // use the value of p then moves to next position
(*p)++; // use the value of p then increment the value
*(p)++; // use the value of p then moves to next position
*++p;   // moves to the next int location then use that value
*(++p); // moves to next location then use that value

2
@alex इसका उपयोग उदाहरण के लिए करता है, कथन पर विचार करें, 'int * a = p ++;' यहां पॉइंटर 'पी' के पहले मूल्य का उपयोग किया जाएगा और उसके बाद पी अगली स्थिति में जाएगा। इसलिए उपरोक्त कथन को निष्पादित करने के बाद 'a' में पिछले स्थान का पता होगा जो 'p' द्वारा इंगित किया गया है और 'p' अगली स्थिति की ओर इशारा करेगा। उपरोक्त के रूप में असाइनमेंट एक्सप्रेशन के लिए पहले 'p' के मान का उपयोग करें और फिर 'p' के इंक्रीमेंट वैल्यू को अगली पोज़िशन में लाने के लिए
Sujith R Kumar

संक्षेप में, मुझे लगता है कि वह "औपचारिक रूप से" असाइन किए गए शब्द के लिए "इसका उपयोग करें" वाक्यांश का उपयोग करता है। बस इतना ही।
Apekshik पाणिग्रही

4

निम्नलिखित विभिन्न "बस इसे प्रिंट करें" सुझावों का एक तात्कालिकता है। मुझे यह शिक्षाप्रद लगा।

#include "stdio.h"

int main() {
    static int x = 5;
    static int *p = &x;
    printf("(int) p   => %d\n",(int) p);
    printf("(int) p++ => %d\n",(int) p++);
    x = 5; p = &x;
    printf("(int) ++p => %d\n",(int) ++p);
    x = 5; p = &x;
    printf("++*p      => %d\n",++*p);
    x = 5; p = &x;
    printf("++(*p)    => %d\n",++(*p));
    x = 5; p = &x;
    printf("++*(p)    => %d\n",++*(p));
    x = 5; p = &x;
    printf("*p++      => %d\n",*p++);
    x = 5; p = &x;
    printf("(*p)++    => %d\n",(*p)++);
    x = 5; p = &x;
    printf("*(p)++    => %d\n",*(p)++);
    x = 5; p = &x;
    printf("*++p      => %d\n",*++p);
    x = 5; p = &x;
    printf("*(++p)    => %d\n",*(++p));
    return 0;
}

यह लौट आता है

(int) p   => 256688152
(int) p++ => 256688152
(int) ++p => 256688156
++*p      => 6
++(*p)    => 6
++*(p)    => 6
*p++      => 5
(*p)++    => 5
*(p)++    => 5
*++p      => 0
*(++p)    => 0

मैंने सूचक पते intएस को दिए ताकि उनकी तुलना आसानी से की जा सके।

मैंने इसे जीसीसी के साथ संकलित किया।


1
मैं ऑपरेशन के बाद x और p का मान शामिल करने के लिए इसे बदलूंगा।
NetJohn

3

"कैसे एक पॉइंटर पते और पॉइंटर के मूल्य में वृद्धि के संबंध में ?" मुझे लगता है कि ++(*p++);वास्तव में अच्छी तरह से परिभाषित किया गया है और आप जो पूछ रहे हैं, जैसे:

#include <stdio.h>

int main() {
  int a = 100;
  int *p = &a;
  printf("%p\n",(void*)p);
  ++(*p++);
  printf("%p\n",(void*)p);
  printf("%d\n",a);
  return 0;
}

यह अनुक्रम बिंदु से पहले एक ही चीज़ को दो बार संशोधित नहीं कर रहा है। मुझे नहीं लगता कि यह अच्छी शैली है, हालांकि अधिकांश उपयोगों के लिए - यह मेरी पसंद के लिए थोड़ा बहुत गूढ़ है।


वास्तव में, कोष्ठक अनावश्यक हैं: ++*p++दोनों मूल्य और सूचक को सफलतापूर्वक बढ़ाएँगे (पोस्टफिक्स ++डेरेफेरेंस से अधिक मजबूत है *, और ++ऑर्डर के कारण उपसर्ग से पहले होता है )। कोष्ठक केवल तब आवश्यक होते हैं जब आपको इसे बढ़ाने से पहले मूल्य की आवश्यकता होती है (*p++)++। यदि आप सभी उपसर्ग जाते हैं, ++*++pतो कोष्ठक के बिना भी ठीक काम करेगा (लेकिन पॉइंटर इंक्रीमेंट के बाद इंगित किए गए मूल्य में वृद्धि)।
विस्फ़ोटक - मोनिका

1
        Note:
        1) Both ++ and * have same precedence(priority), so the associativity comes into picture.
        2) in this case Associativity is from **Right-Left**

        important table to remember in case of pointers and arrays: 

        operators           precedence        associativity

    1)  () , []                1               left-right
    2)  *  , identifier        2               right-left
    3)  <data type>            3               ----------

        let me give an example, this might help;

        char **str;
        str = (char **)malloc(sizeof(char*)*2); // allocate mem for 2 char*
        str[0]=(char *)malloc(sizeof(char)*10); // allocate mem for 10 char
        str[1]=(char *)malloc(sizeof(char)*10); // allocate mem for 10 char

        strcpy(str[0],"abcd");  // assigning value
        strcpy(str[1],"efgh");  // assigning value

        while(*str)
        {
            cout<<*str<<endl;   // printing the string
            *str++;             // incrementing the address(pointer)
                                // check above about the prcedence and associativity
        }
        free(str[0]);
        free(str[1]);
        free(str);

समाजशास्त्र क्या है?
71GA

1
कोड में आप * str ++ देख सकते हैं, अब यहाँ दोनों * और ++ में एक ही पूर्वता है (आम आदमी की अवधि में समान प्राथमिकता) और यह भी * str ++ को * (str ++) या (* str) ++ जैसे कोष्ठक का उपयोग करके अलग नहीं किया जाता है। यह आवश्यक हो जाता है कि इसका मूल्यांकन कैसे किया जाना चाहिए। तो दाएँ से बाएँ का अर्थ है (x = str ++) और फिर (y = * x)
अभिषेक DK
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.