I'm not sure I got what you're asking.
Do you mean why you get a string and not a memory address as output? For the same reason that when you do
1 2
|
const char *p="Hello, World!\n";
std::cout <<p;
|
you don't get a memory address. operator<<() has an overload that takes a const char * as a parameter and interprets is as pointing to a C string.
Or do you mean you can apply the offset operator ([]) to pointers?
1 2
|
const char *p="Hello, World!\n";
std::cout <<p[1];
|
In reality, you can
only apply it to pointers. When you do something like
1 2
|
int a[10];
std::cout <<a[1];
|
What you're really doing is taking a pointer to a, adding 1 to it, and dereferencing that.
1 2 3 4
|
int a[10];
int *p=a;
std::cout <<p[1];
std::cout <<*(p+1);
|
It's important here to make the distinction between pointers and arrays. Pointers are integers that refer to memory locations. Arrays are one of the things that can occupy memory locations. Variables and objects also occupy memory locations. But a pointer can't make a distinction between the two; all it sees is the memory it points to. This means that, depending on how you interpret it, a pointer can point to both a single value or an array of values. This is why in C and C++ it's very important to keep the size of the arrays being pointed to. There's otherwise no way of telling how long the array a pointer points to is. It could be 2^20 elements long, or 1. The pointer won't tell you.
One more thing: In my previous example, a is declared as a stack arrays. Stack arrays are not the same as pointers:
1 2 3 4
|
int a[10];
int *p=a;
p++;
a++; //Error. You can't increment arrays.
|