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+=1
a *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 +=1
y ++
? Pensé que los dos son lo mismo.
c
pointers
post-increment
huy nguyen
fuente
fuente
string
.allocateIntArray
es un mal nombre, ya que parece sermalloc
la matriz de la función, pero no lo hace. Sugiero en sufillIntArray
lugar. 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 deincreasePointer
serif (*ptr != NULL)
? 4) El repartomalloc
es 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.h
no se usa.p+=1
es 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+=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í.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+=1
utilizando 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
src
matriz en otradest
matriz.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