2011-11-21 12 views
57

Supponiamo,Come incrementare l'indirizzo di un puntatore e il valore del puntatore?

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

Quale sarà il seguente codice farà davvero e in che modo?

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

lo so, questo è una specie di disordinato in termini di codifica, ma voglio sapere che cosa realmente accadere quando ci codice come questo.

Nota: Supponiamo che l'indirizzo di a=5120300, sia memorizzato nel puntatore p il cui indirizzo è 3560200. Ora, quale sarà il valore di p & a dopo l'esecuzione di ogni istruzione?

+3

perché non lo esegui nel debugger? –

+15

Beh .. perché non semplicemente * provare * e vedere? 'printf' stamperà un puntatore con% p –

+0

Se sei curioso del comportamento, gioca solo con esso. Basta scrivere un semplice programma c che riporti tutti questi casi d'uso e vedere se ha senso per te. – Cyrus

risposta

91

Innanzitutto, l'operatore * ha la precedenza sull'operatore ++ e gli operatori() hanno la precedenza su tutto il resto. MODIFICA (le cose sono più complicate di così, vedi modifica in basso)

In secondo luogo, l'operatore di numero ++ è uguale all'operatore numero ++ se non le si assegna a nulla. La differenza è numero ++ restituisce il numero e quindi incrementa il numero, e il numero ++ incrementa per primo e poi lo restituisce.

In terzo luogo, aumentando il valore di un puntatore, lo si incrementa in base alla dimensione del suo contenuto, ovvero lo si incrementa come se si stesse iterando in un array.

Quindi, per riassumere il tutto:

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 

Come ci sono un sacco di casi in qui, avrei fatto qualche errore, per favore correggetemi se sbaglio.

EDIT:

così mi è stato sbagliato, la precedenza è un po 'più complicato di quello che ho scritto, vista qui: http://en.cppreference.com/w/cpp/language/operator_precedence

+3

* ptr ++, il valore non viene incrementato, il puntatore è. Questi operatori unari hanno la stessa precedenza ma vengono valutati da destra a sinistra. Il codice significa "prendi il contenuto da dove ptr punta a, quindi incrementa ptr". È un codice C molto comune (e sì, abbastanza confuso). Si prega di correggere questo e rimuoverò il downvote. Lo stesso per * (ptr) ++, la parentesi non fa nulla. – Lundin

+0

Grazie mille Lundin, mi sono perso qualcos'altro? – felipemaia

+0

@Lundin Ciao, la risposta sopra è stata corretta ora? Grazie. – Unheilig

3

Per quanto riguarda "Come incrementare un indirizzo di puntatore e puntatore del valore?" Penso che ++(*p++); è in realtà ben definita e fa quello che stai chiedendo, ad es .:

#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; 
} 

Non è modificando la stessa cosa due volte prima di un punto sequenza. Non penso che sia comunque un buon stile per la maggior parte degli usi: è un po 'troppo criptico per i miei gusti.

8

controllato il programma ed i risultati sono come,

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 
+1

'usalo'. Come ? – alex

+1

@alex usarlo significa, per esempio, prendere in considerazione l'istruzione, 'int * a = p ++;' Qui il primo valore del puntatore 'p' sarà usato per e dopo che p passerà alla posizione successiva. Quindi, in effetti, dopo aver eseguito l'istruzione sopra "a" avremo l'indirizzo della posizione precedente puntata da "p" e "p" indicherà la posizione successiva. Per prima cosa usa il valore di 'p' per l'espressione di assegnazione come sopra e poi incrementa il valore di 'p' per puntare alla prossima posizione –

0

Il seguente è un esemplificazione dei vari "basta stampare" suggerimenti. L'ho trovato istruttivo.

#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; 
} 

Esso restituisce

(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 

io scaccio gli indirizzi puntatore per int s in modo da poter essere facilmente comparati.

L'ho compilato con GCC.

Problemi correlati