我一直认为当你想从一个函数返回一个数组时,唯一的方法就是使用像这样的指针:
char * func();
但昨天,我正在经历K& R,我注意到 错误地认为 char x()[]
也是一个有效的构造。所以我继续对此进行测试,并编写了以下代码:
#include <stdio.h>
#include <stdlib.h>
char string1[10] = "123456789";
char x(void)[10];
int main(void) {
printf("string returned by x() is %s",x());
return EXIT_SUCCESS;
}
char x(void)[10] {
return x;
}
在Windows上使用GCC进行编译时,会产生以下错误:
..\src\07arrreturn.c:7:6: error: 'x' declared as function returning an array
..\src\07arrreturn.c: In function 'main':
..\src\07arrreturn.c:10:2: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'int' [-Wformat]
..\src\07arrreturn.c: At top level:
..\src\07arrreturn.c:14:6: error: 'x' declared as function returning an array
..\src\07arrreturn.c: In function 'x':
..\src\07arrreturn.c:15:2: warning: return makes integer from pointer without a cast [enabled by default]
发生了什么事?我误解了这本书的内容吗?如何从函数中返回多个值(或地址)?是不是因为你只有一个有限大小的CPU寄存器可以保存返回值?如果你必须返回一大块数据,你只能通过将地址返回给它来做到这一点吗?
与char x()[]的交易是什么?甚至使用过这样的东西吗?
编辑:我实际上误读了K&amp; R的东西。请参阅下面的评论。
答案 0 :(得分:5)
char x()[]
也是一个有效的构造
不是原样,在这种背景下并不完全。
您可以使用类似的语法:
声明一个指向数组的指针:char (*arrPtr)[20];
声明一个函数指针数组:void (*foo[20])(void);
取消引用函数调用的返回值(指针):char *foo(); char c = foo()[0];
声明一个返回指向数组的指针的函数:char (*foo())[20]
或与函数指针相同的事情:char (*(*foo)())[20]
您要找哪一个?
答案 1 :(得分:4)
C标准(ISO / IEC 9899:2011)毫不含糊地说:
6.7.6.3函数声明符(包括原型)
<强>约束强>
1函数声明符不应指定函数类型或数组的返回类型 类型。
因此您的代码无效。
答案 2 :(得分:2)
K&amp; R C很老了。在ANSI C(C89)中,不允许返回数组的函数,你看到的是这样的结果。首先,作为返回数组的函数,x()
的声明会出错,由于此错误,x()
永远不会被正确声明,因此被视为返回int
的函数(因为这曾经是默认的返回类型)。然后,返回的int应该被解释为生成最终警告的char *
。
如果需要返回数组,可以将其包装在结构中。否则返回一个指针(确保返回后它指向的内存有效。)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char string1[10] = "123456789";
struct ret_s {
char string1[10];
};
struct ret_s x(void);
int main(void) {
struct ret_s r = x();
printf("string returned by x() is %s\n", r.string1);
return EXIT_SUCCESS;
}
struct ret_s x(void) {
struct ret_s r;
strcpy(r.string1, string1);
return r;
}