Where variables are stored isn't really relevant to how variables differ from pointers. An integer can be in a register, on the stack, or in specifically allocated memory. A pointer can be in these places too.
Think of it this way:
* A character (char) is usually one byte. It's a short number which represents a letter.
* A pointer to a character (char*) is usually four bytes. It's a number which has the address in memory where a character (char) lives.
* By dereferencing a pointer (*ptr_to_char), you tell the language to get the address from ptr_to_char, then look at that address, and get the character from there, or to change the character there (when written like *ptr_to_char = 'x').
* By changing a pointer, you change the address it points to. So, ptr_to_char += 1 moves the pointer, to point to the next character, if there is more than one (a string). It's like moving the character your finger POINTS to in the page of a book. Yes, pointers literally point to things, that's where they get their name from.
It's exactly the same for integers.
However, I didn't use integers as the first example, since they're a little more confusing. Whereas a char is usually a different size from a pointer, an int is usually the same size. Also, a memory address is often just an integer inside the system, so in C, you can mix and match these, with a bit of conversion. Consider:
int i = 1;
int* ptr_to_i = &i;
This defines an integer, with the value 1, and a pointer to an integer, with the value of whatever memory address "i" is stored at. "int j = *ptr_to_i" sets j to the value of i; "int j = ptr_to_i" sets j to the ADDRESS of i. Your compiler should warn about doing that, since you didn't declare j to be a pointer, just to be an integer. However, the compiler won't really care, if you really want to do that.