pointer c pointers post-increment

pointer - Diferencia entre*ptr+= 1 y*ptr++ en C



p++ php (5)

* ptr + = 1: aumenta los datos a los que apunta ptr. * ptr ++: Incrementa el puntero que apunta a la siguiente ubicación de memoria en lugar de los datos a los que apunta el puntero.

Recién comencé a estudiar C, y al hacer un ejemplo sobre pasar puntero a puntero como parámetro de una función, encontré un problema.

Este es mi código de muestra:

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

El problema ocurre en la línea 16, cuando *ptr+=1 a *ptr++ . El resultado esperado debería ser la matriz completa y el número 1, pero cuando uso *ptr++ el resultado es 0.

¿Hay alguna diferencia entre +=1 y ++ ? Pensé que los dos son lo mismo.


Apliquemos paréntesis para mostrar el page

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

Hagámoslo de nuevo con

*ptr += 1 (*ptr) += 1

Y de nuevo con

*ptr++ *(ptr++)

  • En *ptr += 1 , incrementamos el valor de la variable a la que apunta nuestro puntero.
  • En *ptr++ , incrementamos el puntero después de completar toda nuestra declaración (línea de código) y devolvemos una referencia a la variable a la que apunta nuestro puntero.

Este último te permite hacer cosas como:

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++); }

Este es un método común utilizado para copiar una matriz src en otra matriz dest .


El orden de precedencia para los 3 operadores involucrados en su pregunta es el siguiente:

post-incremento ++ > desreferencia * > asignación +=

Puede consultar esta page para obtener más detalles sobre el tema.

Al analizar una expresión, un operador que aparece en una fila estará más ajustado (como entre paréntesis) a sus argumentos que cualquier operador que esté en una fila más abajo. Por ejemplo, la expresión *p++ se analiza como *(p++) y no como (*p)++ .

En pocas palabras, para expresar esta asignación *ptr+=1 utilizando el operador posterior al incremento, debe agregar paréntesis al operador de desreferencia para dar prioridad a esa operación sobre ++ como en este (*ptr)++


La diferencia se debe a la precedencia del operador.

El operador posterior al incremento ++ tiene mayor prioridad que el operador de desreferencia * . Entonces *ptr++ es equivalente a *(ptr++) . En otras palabras, el incremento posterior modifica el puntero, no lo que apunta.

El operador de asignación += tiene menor prioridad que el operador de desreferencia * , por lo tanto *ptr+=1 es equivalente a (*ptr)+=1 . En otras palabras, el operador de asignación modifica el valor al que apunta el puntero y no cambia el puntero en sí.


Muy buena pregunta

En K&R "Lenguaje de programación C" "5.1 Punteros y Direcciones", podemos obtener una respuesta para esto.

"Los operadores unarios * y & se unen más estrechamente que los operadores aritméticos"

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

"Los operadores unarios como * y ++ se asocian de derecha a izquierda ".

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

// Funciona como * (ptr ++).

La forma correcta es:

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