char a; /* A variable that holds a character */
int b; /* A variable that holds an integer */
MyStruct c; /* A variable that holds a structure */
char * x; /* A variable that points to a character */
int * y; /* A variable that points to an integer */
MyStruct * z; /* A variable that points to a structure */
And just to expand a little on this explanation, a pointer is just a variable that holds a memory address. Example:
Given the following declaration, the variable 'a' is shorthand for a memory address that contains the value 5.
int a = 5;
During execution, the value 5 is read directly from the address to which 'a' refers. Like in this case.
int a1 = a;
Here, the value stored at the location represented by 'a' is copied into another address represented by 'a1'. Contrast that with the following pointer declaration, which is going to be interpreted by the compiler in a very different way.
int *b = &a;
'b' is also shorthand for a memory address, but the * tells the compiler to treat it as a pointer, which means that any values found at this address are themselves memory addresses. There are two ways to use a pointer. One is to read the value directly, i.e. the memory address it contains. For example:
int *c = b;
This is saying, take the address stored in b and copy it to c. Both b and c now point to the same thing, in this case 'a' since I assigned its address to b above. And the other is to read the value stored at the address it points to:
int d = *b;
Here, we are reading the address stored in b (the address of a) and then jumping to that address and reading the value there. So, given the assignments above, d will be set to 5.
So pointers are variables, just as non-pointers are. The only difference is that the values they represent are memory addresses rather than integers, characters, or other types.