ok, importantly, you never move boxes (aka memory), you copy values into them, read values from them, etc.
So let me give you a script for a comptuer:
1. create a pointer to an integer on the stack (aka declare a local variable for type int*), call this variable "current ptr". We'll assume this is at address 0x200, and the current value stored in it is "undefined" ...
int *current_ptr;
2. create a new array of 10 integers, and store the address of the start of this array in the variable called "current ptr". We'll assume the array was allocated on the heap starting at memory location 0x300 and running through 0x327. So now the box at 0x200, has the value 0x300 stored in it. So if you read the value of current_ptr, it is 0x300. But if you read the value POINTED TO by current_ptr, you would get an undefined value.
current_ptr = new int[10];
3. initialize the values of each array element to its index. So now the values at 0x300, 0x304, 0x308 ... are 0, 1, 2 respectively. But the value stored in 0x200 is still 0x300
for(int i=0; i<10; i++)
current_ptr = i;
4. Change current pointer to point to the item whose value is 5. So now the value/address 0x314 would be stored in current pointer (aka in the box at 0x200.
while(*current_ptr < 5)
current_ptr++;
NOTE - now that we changes current_ptr and didn't remember the start of the address anywhere, we have a little problem .. we've "lost" the first 5 elements of the array. They are still there at 0x300-0x313 ... but our program no longer knows that. It just has an integer pointer pointed to 0x314 (the middle of the array) ... if we write the following:
for(int i=0; i<10; i++)
printf("%i", current_ptr);
it would print:
5 6 7 8 9
and then it would crash because current_ptr[5] is the address 0x328, 1 byte past the end of the original array of 10 integers we allocated. Basically, we've gone too far - opps!
So "numeric variables" are just boxes of memory. "pointers" are also just boxes of memory. The value in a numeric variable is just a number stored in memory, the value in a pointer variable is just a number stored in memory. The difference is in how we USE the value. If the number 20 is stored in an integer, the computer will support operations like x+x which would be 20+20 => 40. If the number 20 were stored in an integer pointer, it is still the same bit pattern 10100, but the computer will support operations like *x which means use the number stored in x (20) as the address of ANOTHER number ... go to that address and get the value there - so *x + *x means ... go get the number value pointed to by x .. and add it to itself ... so whatever number is stored in the bytes in memory at address 20-23 would be read and used (or if we didn't allocate that memory, we would get a memory access violation exception and our program would crash)