为什么函数必须返回char *而不是char数组?

时间:2017-07-26 19:15:19

标签: c arrays string pointers

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

由于函数的作用是返回一个字符数组,为什么我必须声明我的函数在声明中返回char*而不是char[]

5 个答案:

答案 0 :(得分:5)

因为C的设计方式,阵列不是一流的公民。您既不能返回它们,也不能通过值将它们传递给函数。

如果你想要实现其中任何一个,你必须将数组包装在一个结构中。

>>> np.random.seed(1234)
>>> a = np.random.randint(0,2,(3,3))
>>> b = np.random.randint(11,99,(2,3,3))
>>> a  # Index array
array([[1, 1, 0],
       [1, 0, 0],
       [0, 1, 1]])
>>> b  # values array
array([[[60, 34, 37],
        [41, 54, 41],
        [37, 69, 80]],

       [[91, 84, 58],
        [61, 87, 48],
        [45, 49, 78]]])
>>> m,n = a.shape
>>> I,J = np.ogrid[:m,:n]
>>> out = b[a, I, J]
>>> out
array([[91, 84, 37],
       [61, 54, 41],
       [37, 49, 78]])

答案 1 :(得分:2)

字符串文字"my string"确实有数组类型。请注意,对于包含10 sizeof "my string" s(包括10)的数组,char将评估为'\0'。您可以将"my string"视为标识数组的标识符,并在大多数表达式中衰减到指向数组的第一个元素的指针(但不在例如sizeof表达式中)。

因此,在return语句中,"my string"衰减到指向数组的第一个元素的指针,该元素包含字符串文字(和空终止符)的字符。它是从函数返回的指针,这就是返回类型必须是char *的原因。

对于记录,尽管可以返回指向数组的指针,但甚至无法从C中的函数返回数组。您还可以从函数返回包含数组字段的struct

看看这个示例代码:

#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";
}

节目输出:

sizeof "my string": 10
*("my string" + 1): y
my string

答案 2 :(得分:2)

首先,C不允许您定义返回数组类型的函数;

之类的东西
char printstring(void)[10] { return "my string"; }

根本不被允许,编译器会对你大喊大叫。

其次,因为你要返回的不是数组。

除非它是sizeof或一元&运算符的操作数,或者是用于初始化声明中另一个数组的字符串文字,否则表达式为“N-element array of { {1}}“将被转换(”衰减“)到”指向T的指针“类型的表达式,表达式的值将是数组的第一个元素的地址。

表达式T的类型为“10个元素数组"my string"”。由于它不是char或一元sizeof运算符的操作数,并且因为它不用于在声明中初始化&的数组,所以它“衰变”到char类型的表达式。它的值是字符串中第一个字符的地址,该地址值是您的函数实际返回的值。

这是设计的 - 它是Ritchie在C语言中保存B的数组语义的方式。但是,这意味着C语言中的数组表达式在大多数情况下都不会保留它们的数组。

答案 3 :(得分:0)

在C中,不允许分配给数组变量。

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

那么为什么人们想要定义一个返回数组的函数,如果它的结果​​可以分配给任何东西呢?

答案 4 :(得分:-2)

免责声明:这不是问题的准确答案,因为它是c++,而不是c。但我认为在讨论的背景下这可能很有趣。

c++中,有一种方法可以返回对数组的引用,如下所示:

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

这类似于返回指针而不复制值。但是在普通c可能。