3

Below code prints the entire string. I am confused why its does so.

char test[] = "jeff";
cout<<test<<endl;

The output is "Jeff", I was expecting it to print the value of char array "test", since test is pointer, pointer the first element which is 'J'.

Why is it printing the whole string, when I cout<<test??

Cole Tobin
  • 9,206
  • 15
  • 49
  • 74
  • 1
    If "cout< – 2785528 Aug 21 '14 at 01:56
  • See a [reference](http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt2). – chris Aug 21 '14 at 01:57
  • 1
    [`test` is not a pointer.](http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c) – chris Aug 21 '14 at 02:00
  • @DOUGLASO.MOEN: With a loop. `for (auto p = test; *p; ++p) cout << *p;` – Benjamin Lindley Aug 21 '14 at 02:01
  • @BenjaminLindley Thanks, but I asked the OP what he would do should his expectations had been correct? – 2785528 Aug 21 '14 at 03:26
  • You say the output is `"Jeff"`. Did you mean `"jeff"` (all lowercase)? If you didn't, confusion with pointers may not be your worst problem when you have corrupting RAM. – Cole Tobin Aug 22 '14 at 00:55
  • @chris something that's helped me explain how pointers and arrays are different to someone coming from an OOP background (like myself) is to think of it like inheritance. In C#, that'd be like `public class Array extends Pointer`. Then things like `char[] str = "meh"; char* str2 = str;` can be thought of as `Array str = "meh"; Pointer str2 = str`. "Arrays" degrade to "pointers" because of inheritance. While not the perfect example because you can't cast pointers to arrays in C/C++, it's an analogy that's helped me explain the concept many times. – Cole Tobin Aug 22 '14 at 01:02

3 Answers3

7

Because of operator<< (basic_ostream<charT,traits>& os, const char* s); (#2 "character sequence" in that list) (slightly more technical list). test decays to a pointer, or char*, which then gets printed as a C-string.

It's the exact same reason cout << "Jeff"; works (instead of printing the address of "Jeff").

Cornstalks
  • 37,137
  • 18
  • 79
  • 144
5

The first element is 'j', certainly, but a char* isn't meant to represent only one char, but a string of them. cout will keep reading chars til it find the null char, or '\0'. This is implicitly put there when you use a string literal such as "jeff".

To print only the first char, dereference the pointer to get it like cout<<*test<<endl;.

Gutblender
  • 1,340
  • 1
  • 12
  • 25
  • 2
    Technically, `test` isn't a `char*`. It *decays* to a `char*`. (I know you don't explicitly state that it is a `char*`, but it kind of sounds like you're implying it) – Cornstalks Aug 21 '14 at 02:04
  • @Cornstalks, What do you mean by it decays to char*. "test" does point to the first character of the string right? – Harshanand Nyshadham Aug 21 '14 at 02:08
  • @Cornstalks you make a good point. I glossed over that detail because in the question Harshanand appeared to be solid on that point. – Gutblender Aug 21 '14 at 02:09
  • 2
    @HarshanandNyshadham: technically, `test` is an array (as chris mentioned). Its type is `char [5]`. – Cornstalks Aug 21 '14 at 02:10
  • I would go as far as to kill off all these "technically"s. Confusing arrays and pointers never ends well. – chris Aug 21 '14 at 02:15
  • @HarshanandNyshadham The real difference between a pointer is where the data is stored. A pointer just points to memory, but an array **is** the memory. You can see this more clearly with a `struct`. Still, when you use an array's identifier, you're really using a pointer to the beginning of it. See the top answer to [this question](http://stackoverflow.com/questions/10696024/how-is-the-array-stored-in-memory). – Gutblender Aug 21 '14 at 02:18
  • @Gutblender Thanks for the reply. When I apply same logic to int array. It print the address of the first element in array (makes easy sense to me :)). So this means its "cout" property to handle 'char' and 'int'? for example: int b[] = {1,2,3}; cout< – Harshanand Nyshadham Aug 21 '14 at 02:37
  • @HarshanandNyshadham Good! If you have what you need, consider marking an answer :) – Gutblender Aug 21 '14 at 02:39
  • @chris: Ha, I didn't even realize I was using that word repeatedly. I concur. – Cornstalks Aug 21 '14 at 02:39
  • Since people are being pedantic about how `test` isn't a `char*`, but degrades to it, I'll be pedantic about your claim that `char*` _isn't_ a pointer to one character, but a `string`. Technically, that's incorrect. A `char*` is just that; a pointer to a `char`. Nothing else. Really, the only reason it's treated as a string is because almost every C/C++ code interprets `char*` to represent the imaginary `string` type. – Cole Tobin Aug 22 '14 at 01:11
1

In C++ (as in C), strings are modeled as NUL-terminated character arrays I.e., the last character's ordinal value is 0, in your example it's character with index 4, inserted by the compiler immediately after the last "f" in "jeff". So in many contexts pointers to "char" are assumed to be NUL-terminated; in this case "cout" keeps printing characters until it hits the NUL character at the end, at which point it stops. C++ also has an actual string class, "std::string", that is in many ways superior to char arrays.

davlet
  • 527
  • 3
  • 12
  • +1 for mentioning the `std::string` class. If you want to interact with a C library and need a `char*`, you just call the `std::string.c_string()` instance method. – Cole Tobin Aug 22 '14 at 01:13