The purpose of a pointer is to save the address of a specific variable. Then the memory structure of following code should look like:
int a = 5;
int *b = &a;
In
int a = 5;
int *b = &a;
int *c = &b;
You get a warning because &b is of type int **, and you try to initialize a variable of type int *. There's no implicit conversions between those two types, leading to the warning.
To take the longer example you want to work, if we try to dereference f the compiler will give us an int, not a pointer that we can further dereference.
Also note that on many systems int and int* are not the same size (e.g. a pointer may be 64 bits long and an int 32 bits long). If you dereference f and get an int, you lose half the value, and then you can't even cast it to a valid pointer.