In C, it is better to not cast the result of malloc(). Doing so can hide bugs that the compiler would be able to warn you about, and the bugs in the worst case can cause your program to crash.
int *ptr = malloc(5 * sizeof(int));
ptr now points to memory for 5 ints, and you initialize them with sequential values in your loop. At then end of the loop, the situation can be visualized like this:
+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 |
+---+---+---+---+---+
^
ptr
Now, we can draw a picture to correspond to each line of code.
printf("%d ", *ptr++);//prin1 +---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 |
+---+---+---+---+---+
^
ptr
Since post increment is used, 0 is printed, and ptr is incremented.
printf("%d ", (*ptr)++);//print2 +---+---+---+---+---+
| 0 | 2 | 2 | 3 | 4 |
+---+---+---+---+---+
^
ptr
The dereferenced value 1 is printed, and then post-incremented, so it becomes 2. ptr did not move.
printf("%d ", *ptr);//print3 +---+---+---+---+---+
| 0 | 2 | 2 | 3 | 4 |
+---+---+---+---+---+
^
ptr
Now, the dereferenced value 2 is printed, and nothing was changed.
printf("%d ", *++ptr);//print4 +---+---+---+---+---+
| 0 | 2 | 2 | 3 | 4 |
+---+---+---+---+---+
^
ptr
The pre-increment on ptr moves it to the next element, and the dereferenced value 2 is printed.
printf("%d ", ++*ptr);//print5 +---+---+---+---+---+
| 0 | 2 | 3 | 3 | 4 |
+---+---+---+---+---+
^
ptr
The dereferenced value 2 is pre-incremented, so the value 3 is printed.
malloc()-Wall -Wextra, and handle all warnings appropriately. (You need to add#include <stdlib.h>)