Hi!
Well, this is a long mail. I took the trouble of elaborating a long answer to your interesting question.
Hope it helps!
The concept of pointers comes from the machine language, where variables are handled as memory locations ("address"

.The same concept has been imported into the C language, and later into C++. The ability to use pointers in C and C++ is in my opinion the originality of these languages because it brings the power of assembly language in a high level language (the ability to manage memory). Any programmer in C++ must master the concept of pointers. If you want to skip pointers, just go to Java.
To understand the reason why pointers are so powerful, you need to enter into details. So please forgive me here to recall the basics.
For each variable you are obliged to make a clear difference between
a) its name;
b) its value;
c) its address, i.e the location in memory where the value is stored.
In order to handle addresses, you are obliged to introduce a new type of variable devoted to address storage, which is called pointer.
A pointer is itself a variable, with a value, a name and an associated address.
The value of a pointer is the address where the value of ANOTHER variable can be found.
The association between a name and an address is done in C++ by means of the operator & "address of".
The association between a value and an address is done in C++ by means of the operator * "content of location".
Ex A:
int MyVar=12 ; // declare an integer named "MyVar" and assign a value to it. This integer will be stored in memory, let's say at address 43411D4B.
int * pMyVar ; // declare a pointer named "pMyVar", which will hold the location of an integer. Be careful here that * means "pointer to", it is not a "content of".
pMyVar=&MyVar; // assign the address of MyVar in pMyVar. The value of variable pMyVar is therefore 43411D4B. Operator "address of".
int c; // declare an integer named "c" and allocate 4 bytes in memory to store its future value. These four bytes are located at address, let's say 4587abbf.
c=*pMyVar; // take the value stored in pMyVar, ie at location 43411D4B, and store it into c, ie at location 4587abbf. Then c=12. Operator "content of".
At locations 43411D4B ("c"

and 4587abbf ("myVar"

the same value 12 is stocked. Therefore c is a copy of MyVar.
Now if you change the value of MyVar,
MyVar=15;
c and MyVar now holds two different values at two different locations.
But *pMyVar automatically holds 15. In my example, MyVar and *pMyVar are two different names for the same location, and thus possess the same value. This is an important reason of using pointers; it offers new possibilities of manipulating data, such as in the following, more elaborate example.
Ex B:
Suppose you are dealing with a structure or an object or a table, ie. an entity occupying a large amount of RAM, and say, you want to transmit it to a function. Let us call O this entity, and func, the function.
if you declare the function like this:
void func (entity 0) // transmission by value;
you are actually giving A FULL COPY of O to func. O may be several bytes long, and it takes processor time for the transmission. Second, if func makes any modification to its argument, it will make it on the copy of O. When the function returns, the modifications will not be impacted on the original O.
if you declare the function like this:
void func (entity *O) // transmission by address;
you are telling func WHERE it can find the original O. The address takes up only 4 bytes, so it takes less processor time to transmit the argument. And any modification to O are directly impacted to the original, because you are actually manipulating the original.
The drawback is that you are handling a pointer, and any access to, let's say, a field in the structure O must be done with a special syntax (use of -> and * operators). Once you know the rules, it is very easy to live with this drawback!
I have a poor knowledge of Java, but I have read somewhere (please correct me if I'm wrong) that in Java, all function declarations are of the first type, but the arguments are implicit pointers (called references).
it means that when you call func(O) the address of O is substituted to O, and all calls are implicitely done "by address" (actually "by reference"

, without the programmer noticing that he is using pointers.
C/C++ have the advantage that you know precisely what you are dealing with; but you need to take the trouble of understanding the underlying concepts.
Ex C:
C and C++ are naturally using pointers when dealing with tables.
When you declare a table
int MyTable[12];
you are:
allocating 12 consecutive integers;
declaring a pointer to an int, called MyTable;
assigning to the pointer MyTable, the address of the first integer in the table.
later, an assignment such as:
c=MyTable[6];
means:
take the address stored in MyTable;
add 6*sizeof(int) to this address;
take the value stored in the resulting address;
assign this value to c.
Ex D:
Consider the entry point in C++:
int main( int argc, char **argv); // (you can replace this by either OwlMain or WinMain, depending on your application framework)
What does char **argv mean?
It means that argv is a pointer to a variable of type char *.
what is a variable of type char * ? This means: the address where you can find a variable of type char.
If now you look Ex C: you see that there is no difference between types
char MyString[ANY_LENGTH];
and char * MyString. Because a table of characters (i.e, a string) is handled in C/C++ as a pointer to the first character of the string.
Therefore char **argv means:
the address where I can find a table of pointers to the first characters of several strings !!
In our case, these strings are the command line arguments that are passed to the function.
ex:
"My first string"
"The second string"
"Etc..."
Let's say the M of first string is located at memory 47853666;
T second 78566ffd;
E third a456ee23;
Now argv is a pointer that contains the address, let's say 2321dde1;
and at address 2321dde1 you find the following consecutive bytes:
47853666
78566ffd
a456ee23
Ex E:
More sophisticated uses of pointers.
Advanced data structures such as chained lists;
Associations between classes in objet oriented programming;
etc...
Enough now! If you have interest in Ex E, I can tell you more about it, in a separate mail!
Hope this to be helpful.
Woliwol