Every pointer has a type. A pointer might be a “pointer to an int” (int*), a “pointer to a double” (double*), or a “pointer to a Circle” (Circle*). This information is essential because it tells the compiler how to interpret the data that the pointer points to. For example, given double* p, the compiler knows that if we try to use the memory p points at, it only makes sense to use it as a double.
It is also an error to try to store a value other than a memory address into a pointer. Given int x = 10;, we can’t ask a pointer to store x - that names the value 10, not the memory address of x.
It is possible to declare a pointer with no specific type as a void*. However, because that address has no defined type, the compiler won’t let us do much with that address. It does not know if the address points at data that should be treated as a double, an int, or a Circle.