Q:

Dumping address of a c-string to an ostream?

I am learning pointers and I dont understand how pointers work with C-style strings. 
Why are these two equivalent?
char a[] = "Gme";
char* p = a; //Why am I allowed to assign "Gme" to a pointer (pointer is an address)

cout << p << " " << *(p+1); //Why does it print "gme" with "cout<<p" (I mean, I am printing an address)?

and
char a[] = "Gme";
char* p = &a[0];   // How is this the same as char* p = a;

cout << p << " " << *(p+1);

Overall, I do not understand how pointers work with strings. How are chars stored in memory? If we consider string as an array of chars,why can't I print the address of a char element? 
Thanks in advance :)

A:

This isn't really anything to do with them being C-style strings. It's true for any array. For example, you can do:
int arr[10];
int* p = arr;

The reason you can do this is because there is a standard conversion called array-to-pointer conversion. This converts an expression denoting an array (such as arr above), into a pointer to its first element. We know the first element of arr is an int so the pointer we get from this conversion is an int*.
char a[] = "Gme";
char* p = a;

In this example, we know a is an array of char. It has 4 elements: the letters G, m,  e, and the terminating null character. When you initialise p with a, you are performing array-to-pointer conversion to get a pointer to the arrays first element. The first element is the character G, so p is a pointer to that character.
std::cout (and the rest of the standard I/O library) just has special overloads for when you output a char*. Instead of simply printing the address that the pointer contains, it assumes that the pointer is pointing at the first character in a null-terminated string (and usually it is correct). It gets each letter of the string just be incrementing and dereferencing the pointer you have passed.

A:

Overall, I do not understand how pointers work with strings. How are chars stored in memory?

This is a large topic that has already been answered.
What is the difference between char s[] and char *s? is a good starting point.

If we consider string as an array of chars,why can't I print the address of a char element?

You can.  You just need to do some extra work to clarify to the compiler what it is you want.
There is an overload for the << operator that takes an ostream and a char* which interprets the right operand as a NUL-terminated string.
If you want cout << ... to only see the pointer-ness of p, and not its stringy-ness then cast to void* so that the only options available to the function call dispatcher when choosing which operator<< overloading to use are the ones that perceive it as a pointer.

