In your case
p0 = (char*) p;
because it char *can be used to access any other types. Related, citing C11, chapter §6.3.2.3
[...] When a pointer to an object is converted to a pointer to a character type, the result points to the least significant address byte of the object. Successive increments of the result, up to the size of the object, prints pointers to the remaining bytes of the object.
However, in the case of
printf("Address = %d, value = %d\n", p0, *p0);
undefined , (p0) %d ( "" ). %p void *, -
printf("Address = %p, value = %d\n", (void *)p0, *p0);
,
, ?
, . .:)