char * printstring(void)
{
return "my string";
}
既然这个函数返回的是一个字符数组,那么我为什么要在声明中指定我的函数返回char*
而不是char[]
呢?
由于C语言的设计方式,数组在其中并不是一等公民。你既不能通过值传递将它们传递给函数,也不能返回它们。
如果你想要实现这些功能中的任何一个,你需要将数组包装在一个结构体中。
struct ten_chars{ char chars[10]; };
struct ten_chars printstring(void)
{
return (struct ten_chars){"my string"};
}
main
函数中,你可以使用 printf("%s\n", printstring().chars);
进行输出。但这是一种不太美观的方式。 - Weather Vane"my string"
确实具有数组类型。请注意,sizeof "my string"
将计算为10
,这是一个包含10个char
(包括'\0'
)的数组的预期大小。您可以将"my string"
视为标识符,用于标识数组,并在大多数表达式中衰减为指向数组第一个元素的指针(但不在sizeof
表达式中)。"my string"
会衰减为指向字符串字面量字符数组(以及空终止符)的第一个元素的指针。从函数返回该指针,这就是为什么返回类型必须是char *
的原因。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
char *
而不是char
数组”的答案。 - ad absurdumchar printstring(void)[10] { return "my string"; }
首先,简单地说是不允许的,编译器会因此而报错。
其次,因为你返回的不是一个数组。
除非它是sizeof
或一元&
运算符的操作数,或者是用于初始化声明中的另一个数组的字符串字面值,类型为"N元素T
数组"的表达式将被转换("衰变")为类型为"T
指针"的表达式,表达式的值将是数组的第一个元素的地址。
表达式"my string"
的类型是"10元素char
数组"。由于它既不是sizeof
或一元&
运算符的操作数,也没有用于初始化声明中的char
数组,因此它会"衰变"为类型为char *
的表达式。它的值是字符串中第一个字符的地址,这个地址值才是你的函数实际返回的值。
这是有意设计的——Ritchie的方式在C语言中保留B的数组语义。然而,这意味着C语言中的数组表达式在大多数情况下都不保留它们的数组特性。
char a[] = "test";
char b[5] = a; /* ILLEGAL */
那么,如果函数的结果可以分配给任何东西,为什么还要定义返回数组的函数呢?
static const char (&func())[12] {
return "hello world";
}
这类似于返回指针并且不复制值。但在纯c
中是不可能的。
const char*
。 - Rabbid76char
)。 - alk