When I was trying to cout them
char l[] {'t', 'r', 'y'};
std::cout << l << std::endl;
I got try printed in the terminal. However, when I tried this.
char l[] {'try'};
I only got y.
I came to c from python so lots of things don't make sense to me, so can you explain the difference of these two expressions?
CodePudding user response:
None of your examples are valid.
- The first one has undefined behavior.
Here you definechar l[] {'t', 'r', 'y'}; std::cout << l << std::endl;
l
to be achar[3]
. That's fine. Printing it like you do is however not since theoperator<<
overload you use requires a null terminated string. Yourchar[3]
is not null terminated so theoperator<<
overload will try to find the null terminator out of bounds which causes undefined behavior. A working variant would have been
which would have made it achar l[] {'t', 'r', 'y', '\0'};
char[4]
with a\0
(null terminator) at the end. - The second example tries to create the array from a multibyte character. Single quotes are for individual characters so that's why that interpretation doesn't work. Many compilers will simply refuse to compile it. To create the array from a string literal, use double quotes:
or the idiomatic way:char l[] {"try"};
Both versions will create a null terminated array, just likechar l[] = "try";
char l[] {'t', 'r', 'y', '\0'};
CodePudding user response:
char l[] {'t', 'r', 'y'};
defines l
to be array of three characters with no terminating null character, so using it in std::cout << l
is bad because the insert operator <<
needs the terminating null character to tell it where the end is.
char l[] {'try'};
defines l
to be an array of one character because 'try'
is a single number formed from three characters in an implementation-defined way. Since it is only one number, the size of the array l
is set to be one element. To initialize l
with that number, it is converted to char
, which loses information about the three characters.
char l[] {"try"};
would define l
to be an array of four characters, because string literals (marked by "
instead of '
) automatically include a terminating null character. Also, even though a string literal is “one thing,” there is a special rule that says when a string literal is used to initialize an array, its contents are used to initialize the array. So the array size is four elements because there are four characters in the string.
CodePudding user response:
In this declaration
char l[] {'t', 'r', 'y'};
there is declared a character array that contains exactly three characters. As the array does not contain a string (a sequence of characters terminated with the zero or the so-called null character '\0'
) then the next statement
std::cout << l << std::endl;
invokes undefined behavior because in this case the operator << expects a pointer to a string (an array designator with rare exceptions is converted to pointer to its first element).
Instead you could write for example
std::cout.write( l, sizeof( l ) ) << std::endl;
Otherwise you could initialize the array by a string literal like
char l[] {"try"};
and write
std::cout << l << std::endl;
In this declaration
char l[] {'try'};
there is declared a character array that is initialized by the multicharacter literal 'try'
that has an implementation defined value and the type int
. Multicharacter literals are conditionally supported.
The compiler should issue a message for such a declaration that there is used a narrowing conversion from int
to char
.
Again you may not write
std::cout << l << std::endl;
because the array does not contain a string. It contains only one element with an implementation defined value.
Try this code snippet
char l[]{ 'try' };
std::cout << sizeof( l ) << '\n';
To output the array you could write as already shown above
std::cout.write( l, sizeof( l ) ) << std::endl;
CodePudding user response:
When you insert an array into an output stream, the array argument implicitly converts to a pointer to char. When you pass a pointer to char into an output stream, it must point to a null terminated string of characters. If the pointer is not to a null terminated character string, then the behaviour of the program is undefined. Undefined behaviour should be avoided.
char l[] {'t', 'r', 'y'}; std::cout << l << std::endl;
l
is an array of 3 characters that does not contain a null terminator character. In this example you insert a pointer to non-null terminated string into an output stream and the behaviour of the program is undefined. The program is broken. Don't do this.
char l[] {'try'};
l
is an array of 1 character that does not contain a null terminator character. If you insert this array to an output stream, then the behaviour of the program is undefined. The program is broken. Don't do this.
Note: 'try' is a multicharacter literal. It's type is int
and its value is implementation defined. Multicharacter literals aren't useful very often. What you probably intended to do, is to use a string literal:
char l[] = "try";
The string literal "try" is an array of 4 characters; ending in the null terminator character.