4

So recently, I watched a video where it said that when I defined an array of integers for example

int my_array[] = {1,2,3};

and I printed my_array cout << my_array; then I would get the address of the first integer in memory, but when we define an array of characters like

char my_string[] = "Hello";

then when I try to print my_string cout << my_string it returns Hello, similarly with pointers when we define a pointer to characters

char mystring[] = "HELLO";
char *my = mystring;
cout << my << endl;//HELLO

and we try to print the pointer variable it returns the string.

Now I've read this article and I read that the string takes the memory address with him. But I still can't figure out why they are not the same and why an array of chars prints the string literal and the int array prints the address of the first one.

Thanks in advance.

Alex
  • 840
  • 7
  • 23
  • `char *my = mystring;` -> `char *my = my_string;`? `why an array of chars returns the string literal` you mean that doing `cout << mystring` it __prints__ the string? – KamilCuk Mar 29 '20 at 19:13
  • sorry fixed the typo – Alex Mar 29 '20 at 19:14
  • They both return the address of the first one. That's how strings are represented in C: as a pointer to a sequence of characters terminated by a '\0' character. (When converted to a pointer at least; int[] will decompose to int* but is initially different.) – Rup Mar 29 '20 at 19:14
  • @UlrichEckhardt sorry, wrote a wrong thing, see my edit – Alex Mar 29 '20 at 19:16
  • 2
    Does this answer your question? [cout << with char\* argument prints string, not pointer value](https://stackoverflow.com/questions/17813423/cout-with-char-argument-prints-string-not-pointer-value) – flowit Mar 29 '20 at 19:18
  • the difference is that char arrays are treated special in C, a string is an array of characters with an ending \0 value, that is why when you print a string the function knows when to stop. – AndersK Mar 29 '20 at 19:18
  • @flowit No it does not entirely, my question is about why when I print the array name it does not return the address of the first char and im only referring to a pointer as an example. – Alex Mar 29 '20 at 19:24

5 Answers5

5

why an array of chars returns the string literal and the int array returns the address of the first one.

I assume the word "returns" is meant to "print".

Because the non-member std::ostream::operator<<(ostream&, const char *) overload iterates over the memory the char* pointer points to and prints the content of it, while there is no std::ostream::operator<<(int*) overload, so int* is casted to const void* and std::ostream::operator<<(const void*) overload is used to print the value, and that function prints the value of the pointer.

You can still print the value of the pointer to string by casting it manually:

cout << static_cast<void*>(my_string) << endl;
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
4

This is a hangover from C and the fact that the standard library has to support C style strings (which are char* null terminated). To this end std::cout has an overload for const char* which treats it as a C style string and prints up to a null termiator.

Printing the address is the normal behavior for a pointer being passed to std::cout (hence your int pointer memory location printout).

Object object
  • 1,939
  • 10
  • 19
3

my_array would contain the address of the first integer in memory,

No. my_array would contain the three integers in memory.

if i do cout << myarray << endl then that would print the address of the first item in memory

Yes. That is how character streams are specified to behave. When you insert a pointer, the address will be printed. Except in the case you insert a pointer to char which is treated differently.

and how is it treated differently?

As per documentation, the pointed character, and its siblings will be printed until the null teminator character is reached.

eerorika
  • 232,697
  • 12
  • 197
  • 326
1

Actually my_array is an int[3], and mystring is a char[6].

The reason the cout << my_string; prints a string is because these conversions get applied char[6] -> char const *, and the ostream operator<< knows to treat a char const * as a string.

For the cout << my_array, the conversion would be int[3] -> int * -> void const *. The ostream operator<< on a void const * simply prints the address.

cigien
  • 57,834
  • 11
  • 73
  • 112
1

This declaration of an array of characters

char my_string[] = "Hello";

is equivalent to the following declaration

char my_string[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

That is the elements of the array are initialized by the characters of the string literal including its terminating zero.

Used in expressions arrays with rare exceptions are converted to pointers to their first elements.

For example if you are using the sizeof operator then an object of an array type is not converted to pointer to its first element. This one of rare exception.

Here is a demonstrative program

#include <iostream>

int main() 
{
    int my_array[] = { 1, 2, 3 };
    char my_string[] = "Hello";

    std::cout << "sizeof( my_array ) = " << sizeof( my_array ) << '\n';
    std::cout << "sizeof( my_string ) = " << sizeof( my_string ) << '\n';

    return 0;
}

Its output is

sizeof( my_array ) = 12
sizeof( my_string ) = 6

But for example when an object of an array type is used as an operand of the operator * then it is converted to pointer to its first element.

Here is another demonstrative program

#include <iostream>

int main() 
{
    int my_array[] = { 1, 2, 3 };
    char my_string[] = "Hello";

    std::cout << "*my_array = " << *my_array << '\n';
    std::cout << "*my_string = " << *my_string << '\n';

    return 0;
}

The program output is

*my_array = 1
*my_string = H

In the C++ Standard there is defined the overloaded operator << to output strings (sequence of characters terminated by the zero character) pointed to by a pointer to char.

So if you will write

std::cout << my_string << '\n';

then in the call of this operator << the character array is implicitly converted to pointer to its first element and the pointed string is outputted.

For integer arrays the operator << is defined such a way that it just outputs the address of the array that is the address of its first element.

Here is a demonstrative program.

#include <iostream>

int main() 
{
    int my_array[] = { 1, 2, 3 };
    char my_string[] = "Hello";

    std::cout << my_array << '\n';
    std::cout << my_string << '\n';

    return 0;
}

Its output might look like

0x7ffdcfe094e4
Hello

If you want that for a character array there would be selected the overloaded operator << that outputs the address of the array then you should cast the array (that is implicitly converted to pointer to its first element) to the type void *.

Here is one more demonstrative program.

#include <iostream>

int main() 
{
    int my_array[] = { 1, 2, 3 };
    char my_string[] = "Hello";

    std::cout << my_array << '\n';
    std::cout << static_cast<void *>( my_string ) << '\n';

    return 0;
}

Its output might be

0x7ffef7ac0104
0x7ffef7ac0112
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335