Mejor respuesta
(int *) p es una conversión de tipo explícita para el valor almacenado en la variable p, al tipo de un puntero cuya dirección apunta a un número entero. El valor que almacena p es una dirección de memoria del 1er byte de los 4 que se utilizan para almacenar dicho entero de 32 bits (4 bytes).
Un puntero almacena un número que debería ser la dirección a una ubicación específica en la memoria (Heap o Stack). El tipo de datos almacenados en esa ubicación podría ser cualquier cosa , y en esta expresión, estamos especificando (o más bien asumiendo) que es un entero de 4 bytes.
El valor de p se puede convertir antes de asignarlo a otro puntero –
int *c = (int *) p;
O bien, podría desreferenciarse para recuperar el valor almacenado en la dirección mantenida por p como tal –
int c = *((int *) p);
O si p es un puntero en sí mismo, podría desreferenciarse sin él siendo explícitamente tipificado porque sabemos que el valor almacenado en él es un entero de 4 bytes.
En aras de la simplicidad, no he verificado los punteros como nulos. Es muy importante que verifique que un puntero sea nulo, porque desreferenciar un puntero nulo da como resultado un bloqueo.
Ejemplo de un puntero nulo comprobar –
if (p != null)
printf(“int is ‘\%d’”, *p);
Ahora asumiendo el la dirección es correcta y que el puntero no es nulo, y que el tipo de datos almacenados en la ubicación de la memoria es de hecho un número entero, su consola lo imprimirá correctamente .
Aquí hay un artículo detallado y bien explicado que encontré hace unos años, sobre cómo leer punteros en c – Regla en sentido horario / espiral
Respuesta
Para entender lo que (int *) está haciendo allí, es útil entender lo que está haciendo malloc (sizeof (int)). Lo desglosamos de derecha a izquierda.
Primero, tenemos un tamaño de (int). Este es un valor que representa el número de bytes necesarios para representar un número entero en la memoria. Esto podría ser 4 o algún otro número dependiendo de la computadora en la que estemos programando.
Entonces, la función malloc () está obteniendo un parámetro como 4, a la malloc (4). Esta función pregunta al Biblioteca C para irse a algún lugar de la memoria y reservar 4 bytes (que resulta ser exactamente el tamaño correcto para contener un número entero).
Ahora la función malloc siempre devuelve la dirección de esa memoria. Recuerde esa computadora la memoria se distribuye en serie y cada dirección de la memoria es única. Ahora malloc () no es una función muy inteligente; le dices cuánta memoria quieres y te dice «aquí está». No sabe qué desea poner en esa memoria; solo sabe cuánta memoria solicitó.
Debido a que malloc () no sabe lo que quiere poner en esa memoria, devuelve un tipo llamado (void *), es decir, una dirección de memoria arbitraria, también conocida como puntero. En la mayoría de las computadoras modernas, una dirección es un valor de 64 bits, que se puede representar en 8 bytes de memoria, pero las computadoras difieren r, y diferentes computadoras pueden devolver diferentes tamaños. Entonces, malloc () puede devolver 8 bytes de datos, en formato (void *).
Por último, necesitamos ingresar a esa memoria que nos dio malloc (), para que podamos tratarla como si tuviera un entero. ¿Como hacemos eso? malloc () nos acaba de dar un puntero a algún recuerdo en el espacio en algún lugar. Lo hacemos diciéndole al compilador que la dirección de memoria que obtuvimos de malloc () es realmente la dirección de un número entero. De ahí su (int *).
Ahora que ha pasado por todo eso, el compilador entonces entiende completamente lo que quería, porque se ha tomado la molestia de describir cada paso: quiere un dirección apuntando a una ubicación de cuatro bytes en la memoria, que a su vez contiene un número entero.
¡Y eso es lo que significa toda la expresión!