0

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 :)

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
khajvah
  • 4,889
  • 9
  • 41
  • 63
  • arrays in c are just pointers to a buffer implicitly allocated on stack (if not in global scope)... nothing else. that's why you can use pointer and char array – V-X May 20 '13 at 17:28
  • @V-X: Arrays in C are not pointers. `sizeof(a)` is proof of this. – Mooing Duck May 20 '13 at 17:39

3 Answers3

5

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.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • Thank you very much.. This was the best answer. I now start to understand. Though there are some misunderstandings, I can figure out myself now.. You did the most job. Thanks :) – khajvah May 20 '13 at 17:48
3

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.

Community
  • 1
  • 1
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
-1

A C-String is an array that consists of char elements.

An array is a series of values in memory which cannot be stored in a single variable (since variables generally have a limit of 64 bits), so the variable points to the first element in the array (eg. contains the address of the first element).

So char a[] = "Gme" creates an array consisting of "G", "m" and "e" stores it in memory, and a contains the address of the first element ("G" in this case).

char* p = a; is valid because a was implicitly created as a pointer, so you are just re assigning the address of the first element of the array to p.

char* p = &a[0]; is valid because a[0] is the value at the 0'th element of a. By adding &, you are taking the address of the 0'th element of a. So p now points to the first element of the array a so now p can be treated as an array as well.

Brad
  • 10,015
  • 17
  • 54
  • 77