Según tengo entendido, en la línea marcada como 'línea 2' del siguiente código, la expresión (*ptr)++ debería generar un error de "valor necesario" porque *ptr evalúa como un valor constante de i=1 , que no es valor?
Entonces, ¿por qué el programa funciona con éxito? ¿O estoy en algún lugar equivocado en mis conceptos? En caso afirmativo, por favor ilumíneme sobre esto.
int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0; i<5; i++) *(ptr + i) = i; printf("%d ", *ptr++); //line 1 printf("%d ", (*ptr)++); //line 2 printf("%d ", *ptr); //line 3 printf("%d ", *++ptr); //line 4 printf("%d ", ++*ptr); //line 5 }Estás teniendo un concepto erróneo. El resultado de (*ptr) es lvalue, sobre el cual se puede aplicar el operador de incremento posterior.
Entonces, en tu caso,
printf("%d ", (*ptr)++); //line 2está bien.
Para citar el estándar C11 , capítulo §6.5.3.2, Operadores de dirección e indirección , (énfasis mío)
El operador unario
*denota direccionamiento indirecto. Si el operando apunta a una función, el resultado es un designador de función; si apunta a un objeto, el resultado es un lvalue que designa el objeto.
FWIW, si *ptr no fuera un lvalue, habrías obtenido un error al escribir algo como *ptr = 5 también, ¿no?
¿Qué pasa con int i = 0; i++; . Si i es 0, ¿entonces 0++ es válido? La respuesta es, por supuesto, no, 0++ (y 1++ ) no son válidos. ++ no se aplica al valor , se aplica al objeto (en este caso i , o en su caso, el objeto señalado por *ptr ).
Un lvalue es algo que se refiere a algún lugar en la memoria que puede contener un valor. Así que si *ptr=10; entonces *ptr es lvalue .