C函数返回一个数组

时间:2013-05-24 06:06:31

标签: c

我一直认为当你想从一个函数返回一个数组时,唯一的方法就是使用像这样的指针: 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的东西。请参阅下面的评论。

3 个答案:

答案 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;
}