1) This is a little tricky. You are correct in thinking that 'terry' just contains an address here.
The reason "hello" is printed and not the address is because iostream (cout) makes a special case
for char and const char pointer to treat them as string data... since that's usually the intent.
For any other
kind of pointer... cout will print the address. But for char pointers.. cout will go to
that address and print the string data contained there.
If you want to display the address of 'terry' here, you'd have to cast it to some other type of pointer. A generic
pointer will do. This will not change the variable in any way... but will "trick" iostream into thinking it's not a char pointer, and therefore it will not print the string data, but will just print the address:
cout << static_cast<const void*>(terry) << endl;
2) You should never, ever, ever do this. Compilers only really allow this to support legacy code. Properly written code should never do this.
The reason why string literals should always be const is because they are loaded into memory when the program is started up... and the memory they are loaded into may not be writable. And even if it is... multiple pointers may refer to it (if the string data is pooled) and changing the string data may have unintended consequences.
So yeah.. to answer your question.... it works because the compiler is being friendly because it wants to support old code. But really... in a perfect world... the compiler should refuse to compile this.