char * printstring(void)
{
return "my string";
}
由于函数的作用是返回一个字符数组,为什么我必须声明我的函数在声明中返回char*
而不是char[]
。
答案 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
中不可能。