Recién comencé a estudiar C, y cuando hice 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 modifico *ptr+=1a *ptr++. El resultado esperado debería ser toda la matriz y el número 1, pero cuando uso*ptr++ el resultado es 0.
¿Hay alguna diferencia entre +=1y ++? Pensé que los dos son lo mismo.
c
pointers
post-increment
huy nguyen
fuente
fuente

string.allocateIntArrayes un mal nombre, ya que parece sermallocla matriz de la función, pero no lo hace. Sugiero en sufillIntArraylugar. 2) No utiliza el valor de retorno deallocateIntArray. Le sugiero que cambie el tipo de retorno avoid. 3) No debeif (ptr != NULL)en función deincreasePointerserif (*ptr != NULL)? 4) El repartomalloces innecesario. Ver el comentario de Sourav arriba. 5) Esto:for (int i = 0; i < 10; i++){ printf("%d\n", p1[i]); }yprintf("%d\n", *p1); p1--;debe incluirseif(p1 != NULL). 6)string.hno se usa.p+=1es como++p, no comop++Respuestas:
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 que*ptr+=1es 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í.fuente
*p++y*++p. La precedencia del operador de este último es clara, sigue la del primero.El orden de precedencia para los 3 operadores involucrados en su pregunta es el siguiente:
post-incremento
++> desreferencia*> asignación+=Puede consultar esta página para obtener más detalles sobre el tema.
En pocas palabras, para expresar esta asignación
*ptr+=1utilizando el operador posterior al incremento, debe agregar paréntesis al operador de desreferencia para dar prioridad a esa operación++como en este(*ptr)++fuente
Apliquemos paréntesis para mostrar el orden de las operaciones.
Hagámoslo de nuevo con
Y de nuevo con
*ptr += 1, incrementamos el valor de la variable que apunta nuestro puntero .*ptr++, incrementamos el puntero después de que se completa 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:
Este es un método común utilizado para copiar una
srcmatriz en otradestmatriz.fuente
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"
"Los operadores unarios como * y ++ se asocian de derecha a izquierda ".
// Funciona como * (ptr ++).
La forma correcta es:
fuente
* 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.
fuente