2011-11-21 16 views
57

Vamos a suponer,¿Cómo incrementar una dirección de puntero y el valor de un puntero?

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

¿Cómo será el siguiente código hará realidad y cómo?

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

lo sé, esto es un poco complicado en términos de codificación, pero quiero saber lo que realmente va a pasar cuando codificamos como este.

Nota: supongamos que la dirección de a=5120300, se almacena en el puntero p cuya dirección es 3560200. Ahora, ¿cuál será el valor de p & a después de la ejecución de cada declaración?

+3

¿por qué no solo lo ejecuta en el depurador? –

+15

Bueno ... ¿por qué no simplemente * probar * y ver? 'printf' imprimirá un puntero con% p –

+0

Si tiene curiosidad por el comportamiento, simplemente juegue con él. Simplemente escriba un programa c simple que revise todos estos casos de uso y vea si tiene sentido para usted. – Cyrus

Respuesta

91

En primer lugar, el * operador tiene prioridad sobre el operador ++, y los operadores() tienen prioridad sobre todo lo demás. EDITAR (las cosas son más complicadas que eso, ver edición inferior)

En segundo lugar, el operador de número ++ es el mismo que el operador ++ si no los está asignando a nada. La diferencia es number ++ returns number y luego incrementa el número, y ++ number se incrementa primero y luego lo devuelve.

En tercer lugar, al aumentar el valor de un puntero, lo estás incrementando por el tamaño de su contenido, es decir, lo estás incrementando como si estuvieras iterando en una matriz.

lo tanto, para resumir todo:

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 

Como hay una gran cantidad de casos en que aquí, podría haber hecho algún error, por favor, corríjanme si me equivoco.

EDIT:

Así que estaba mal, la precedencia es un poco más complicado que lo que escribí, ver aquí: http://en.cppreference.com/w/cpp/language/operator_precedence

+3

* ptr ++, el valor no se incrementa, el puntero sí. Estos operadores únicos tienen la misma precedencia pero se evalúan de derecha a izquierda. El código significa "tomar los contenidos desde donde apunta ptr, luego incrementar ptr". Es un código C muy común (y sí, bastante confuso). Por favor, corrige esto y eliminaré el voto a favor. Lo mismo para * (ptr) ++, el paréntesis no hace nada. – Lundin

+0

Muchas gracias, Lundin, ¿extrañé algo más? – felipemaia

+0

@Lundin Hola, ¿la respuesta anterior está corregida ahora? Gracias. – Unheilig

3

Con respecto a "Cómo incrementar una dirección de puntero y el puntero de ¿valor?" Creo que ++(*p++); es en realidad bien definidos y que lo que está pidiendo, por ejemplo .:

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

No es la modificación de la misma cosa dos veces antes de un punto de secuencia. Aunque no creo que sea un buen estilo para la mayoría de los usos, es demasiado críptico para mi gusto.

8

comprobado el programa y los resultados son como,

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

'usarlo'. cómo ? – alex

+1

@alex use it significa, por ejemplo, una declaración, 'int * a = p ++;' Aquí el primer valor del puntero 'p' se usará para y después de que p se moverá a la siguiente posición. Entonces, en efecto, después de ejecutar la declaración anterior, 'a' tendrá la dirección de la ubicación anterior apuntada por 'p' y 'p' apuntará a la siguiente posición. Primero se usa el valor de 'p' para la expresión de asignación como arriba y luego se incrementa el valor de 'p' para apuntar a la siguiente posición –

0

La siguiente es una ejemplificación de los diversos "simplemente imprimirlo" sugerencias. Lo encontré instructivo.

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

Devuelve

(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 

yo echo las direcciones puntero a int s para que pudieran ser comparados fácilmente.

Lo compilé con GCC.

Cuestiones relacionadas