to understand why sizeof(pointer) is always 8 yet the sizeof(type-pointed-to-by-pointer) ‘varies’(1,4,8,etc bytes), you have to understand what a pointer really is. A pointer is just another variable except that it STORES A MEMORY ADDRESS. memory addresses are 8 bytes(because the 8 bytes are large enough to store the unbelievably large numbers representing memory cell addresses as memory can be quite large, imagine 64TB of memory for example).
For this reason, sizeof(pointer) is 8 as the pointer stores the MEMORY ADDRESS of memory but NOT the value of the type the memory address points to!
To clarify this. imagine the following code;
line 1: int n=4;
line 2: int *np = &n;
line 1 declares an integer n with value 4. What the compiler really does here is reserve memory large enough to store an integer(4 bytes) and store the value 4 in this reserved memory. The address of the FIRST memory cell in the reserved memory is accessed by &n.
line 2 declares a POINTER to an integer. The keyword here is pointer. The compiler ‘knows’ that every pointer stores a memory address and every memory address(the figure) can be contained in 8 bytes of memory hence the compiler reserves 8 bytes of memory and in this, stores the address of the FIRST memory cell of the address of n(denoted by &n)
It is clear that the pointer DOES NOT store the value of n(which is 4 bytes for an int) but rather the address(which is 8 bytes) of the first memory cell of the memory in which the value of n is stored
With that arrangement, when the compiler finds a line that deferences the pointer(eg int n2 = *np;), all it does is look for the address of the pointer(&np), read the value in that address(np, or the address of n, &n) then go to that address and finally read the value in that address