You were correct in your examples, so your understanding what the & and * operators are for is good.
To be honest, one does not use the &-operator often for the reason you already figured out for yourself: there is little information in the address itself. However, if you look at them a little differently, namely what these addresses point at, they become very useful. For nifty programs as well as shooting yourself repeatedly in the foot with a double-barrelled shotgun. I ain't kiddin' ya.
To give an example where pointers are invaluable, consider allocating memory. There are various ways of doing that on the Amiga: you can call on the system function AllocMem(), but if your fancy runs to programs which should run on other systems too, you would use malloc(). In any case, these functions do some internal housekeeping, ask the OS whether you can have what you ask for, and some other things we needn't go into right now. What interests us at the moment is what they return: a pointer! That pointer is (of course) an address, but it's pointing at an area of memory which is now yours to abuse. You access that memory via the pointer. Here's an example:
void *MyMem;
MyMem = AllocMem(1000, MEMF_PUBLIC);
MyMem now 'points' to an area in memory where we have 1000 bytes at our disposal. To access that memory, we need to apply a second technique, because we've defined MyMem to point at 'void'---in other words, an unknown type. (Make it a habit to try and avoid void where you can.) Suppose we want 1000 integers:
int *MyMem, j;
MyMem = (int *)AllocMem(1000*sizeof(int), MEMF_PUBLIC);
for (i=0; j<1000; j++)
MyMem[j]=j;
First we declare MyMem to be a pointer to int, and then we allocate the memory. The first (int *) is called a cast, an instruction to the compiler to change the type of the result of the proceeding expression to what you specify. AllocMem() returns a void *, and that is not equal to an int *. Note that 'equal' means 'equal in size as well as type': while there is no size difference between int * and void *, there is a type difference. (You could cast a char into an int by doing (int), but that would likely crash the machine as an int is 32 bits, while a char only 8. You'd be accessing a region of 8 bits as if it contained 32, and that is likely going to crash the program.) Then we need to take into account that an int takes not one byte, but four, but we don't specify the four: we specify its size transparently by writing sizeof(int).
And after all that, MyMem is now indistinguishable from an array. You can access it as if you had written:
int MyMem[1000], j;
for (i=0; j<1000; j++)
MyMem[j]=j;
The assignment is in fact compiled to exactly the same code as in the pointer-example.
There are more uses to pointers: they provide a fast means of handing over large amounts of data without unnecessary copying. Suppose that you are working on an image processing program and need to pass on the information of a large graphic from one function to another. You can ask the system to copy that information over every time, but that is a huge waste of resources. It is much easier and faster to have one function tell the other: look, here's a pointer to where you can find the information you need, happy processing. You will see that happen a lot of times once you begin with Amiga system programming. In fact, the Amiga would not exist if it weren't for this property.
It is also the reason why pointers are such great ways of shooting yourself in the foot. There are no checks on their validity: you cannot tell whether a pointer is actually pointing at the information it is supposed to be pointing. That is why you should always strive to use casts: it helps the compiler help you because it is much better at spotting type inconsistencies. That is still no guarantee things are bug-free, but at least the most glaring errors will be caught. (The disadvantage is that if things do go wrong, debugging is not fun at all.)
I hope this has improved your understanding why you would want to use pointers. But don't assume that you can't do without them: many modern languages don't have pointers any longer and rely on other means of passing information along.