Why should the function return a char * array but not a char array?
Because due to the fact that C was designed, arrays are not first-class citizens. You cannot return them and pass them to functions by value.
If you want to achieve any of these things, you will have to wrap the array in a struct.
struct ten_chars{ char chars[10]; };
struct ten_chars printstring(void)
{
return (struct ten_chars){"my string"};
}
source to share
A string literal "my string"
is of type array. Note that this sizeof "my string"
will evaluate to as 10
expected for an array that contains 10 char
(including '\0'
). You can think of it "my string"
as an identifier that identifies an array, and decays to a pointer to the first element of the array in most expressions (but not in expressions, for example sizeof
).
So, in the return statement, it "my string"
decays to a pointer to the first element of the array that contains the characters of the string literal (and null terminator). It is this pointer that is returned from the function, so the return type must be char *
.
For the record, it's not even possible to return an array from a function in C, although you can return a pointer to an array. You can also return struct
which contains the array field from the function.
Take a look at this sample code:
#include <stdio.h>
char * getstring(void);
int main(void)
{
printf("%s\n", getstring());
return 0;
}
char * getstring(void)
{
printf("sizeof \"my string\": %zu\n", sizeof "my string");
printf("*(\"my string\" + 1): %c\n", *("my string" + 1));
return "my string";
}
Program output:
sizeof "my string": 10 *("my string" + 1): y my string
source to share
First, C doesn't allow you to define a function that returns an array type; something like
char printstring(void)[10] { return "my string"; }
just isn't allowed and the compiler will yell at you over it.
Second, because what you are returning is not an array.
sizeof
Unless it is an operand of operators or unary &
, or is a string literal used to initialize another array in a declaration, an expression of type "N-element array of T
" will convert ("decay") to an expression of type "pointer to T
", and the value of the expression will be the address of the first element in the array.
The expression "my string"
is of type 10-element array char
. Since it is not an operand of operators sizeof
or unary &
, and since it is not used to initialize an array char
in a declaration, it "decays" into a type expression char *
. Its value is the address of the first character in the string, and that address value is what your function actually returns.
This by design was Ritchie's way of sorting to preserve the semantics of an array B in C. However, this means that array expressions in C do not preserve their massiveness in most cases.
source to share
Disclaimer: This is not an accurate answer to the question, as it is about c++
, not c
. But I thought it might be interesting in the context of this discussion.
There c++
is a way to return a reference to an array, which might look like this:
static const char (&func())[12] {
return "hello world";
}
This is similar to returning a pointer and does not copy values. But in c
maybe < not .
source to share