简体   繁体   中英

Why does the function have to return a char * but not a char array?

char * printstring(void)
{
    return "my string";
}

Since what the function does is return a character array why do I have to state that my function returns char* and not char[] at the declaration.

Because because of the the way C was designed, arrays are not first-class citizens in it. You can neither return them nor pass them to a function by value.

If you want achieve either of those things, you'll 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"};
}

The string literal "my string" does have array type. Note that sizeof "my string" will evaluate to 10 , as expected for an array that holds 10 char s (including the '\\0' ). You can think of "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, eg, sizeof expressions).

So, in the return statement, "my string" decays to a pointer to the first element of the array that holds the characters of the string literal (and the null terminator). It is this pointer that is returned from the function, and this is why the return type must be char * .

For the record, it is not even possible to return an array from a function in C, though you can return a pointer to an array. You can also return a struct that contains an array field from a function.

Take a look at this example 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

Firstly, C doesn't allow you to define a function that returns an array type; something like

char printstring(void)[10] { return "my string"; }

simply isn't allowed, and the compiler will yell at you over it.

Secondly, because what you are returning isn't an array.

Except when it is the operand of the sizeof or unary & operators, or is a string literal used to initialize another array in a declaration, an expression of type "N-element array of T " will be converted ("decay") to an expression of type "pointer to T ", and the value of the expression will be the address of the first element of the array.

The expression "my string" has type "10-element array of char ". Since it isn't the operand of either the sizeof or unary & operators, and since it isn't being used to initialize an array of char in a declaration, it "decays" to an expression of type char * . Its value is the address of the first character in the string, and that address value is what your function is actually returning.

This is by design - it was Ritchie's way of kind-of-sort-of preserving B's array semantics in C. However, it means that array expressions in C do not retain their array-ness in most circumstances.

In C it is not allowed to assign to an array variable.

char a[] = "test";
char b[5] = a; /* ILLEGAL */

So why then would one want to defined a function returning an array, if its result could be assigned to anything?

Disclaimer: this is not intended as an exact answer to the question since it is about c++ , not c . But i thought that it could be interesting in context of this discussion.

In c++ there is a way to return a reference to an array which could look like the following:

static const char (&func())[12]  {
    return "hello world";
}

This is similar to returning a pointer and does not copy the values. But it is not possible in plain c .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM