使用指针返回向量的好方法

时间:2017-07-13 13:33:20

标签: c arrays pointers

我读过关于C中指针的理论,但我只是心中有困惑。

想象一下,我调用一个方法,它必须使用指针返回一个浮点数组(而不是return语句)。

第一点:我方法的负责人必须这样:myMet([somearguments], float* myvector)

第二点:是否建议在我方法的主体中创建另一个数组,填充它然后执行

*myvector = thatarray

我很遗憾地提出这样一个基本问题,但C中的指针似乎对我很不友好

2 个答案:

答案 0 :(得分:2)

我假设您不希望以某种方式“硬编码”阵列的大小。所以你可能已经有了这样的想法:

(注意,损坏的代码如下

float *foo(void)
{
    float x[] = { 0, 1.3, 27.4 };
    return x;
}

这有多个问题,第一个是根本不起作用:你返回一个指向局部变量的指针,一个局部变量有自动存储持续时间,所以一旦留下范围,它就不再存在了。从此函数中,您将获得一个指向任何有效位置的指针。

如何正确地做到这一点,有多种可能性。惯用的C解决方案是你的调用代码提供了实际的数组,这在你可以对所需大小做出很好假设的所有情况下都是可行的:

size_t foo(float *arr, size_t size)
{
    float x[] = { 0, 1.3, 27.4, -1.5, 23 };
    size_t i;
    for (i = 0; i < size && i < 5; ++i)
    {
        arr[i] = x[i];
    }
    return i;
}

int main(void)
{
    float x[20];

    // would return 5:
    size_t elements = foo(x, 20);
}

如果可行,则必须在函数中使用malloc()。你仍然可以返回大小,例如使用如下签名修改提供的指针:

size_t foo(float **arr)
{
    size_t elements = 5;
    *arr = malloc( elements * sizeof(**arr) );
    // check *arr for NULL, if ok fill it
}

int main(void)
{
    float *x;
    size_t elements = foo(&x);
    // process results
    free(x);
}

或者,我个人更喜欢的是,你可以定义一个包含大小的struct并返回:

struct floats
{
    size_t n;
    float vals[];
}

struct floats *foo(void)
{
    size_t elements = 5;
    struct floats *x = malloc(sizeof(*x) + elements * sizeof(float));
    // check for NULL, handle error ...

    x->n = elements;
    // fill elements in x->vals ...

    return x;
}

请注意,虽然这是struct,但您不能只返回结构本身。由于灵活的数组成员,它的类型是不完整(因此在编译时,大小是未知的),因此您只能返回指向它的指针。但是如果你事先知道大小,你应该去找我的第一个替代方案(让调用者提供数组)。

作为与您的问题无关的一般提示:使用float 非常非常一个好主意。几乎在所有情况下,您都希望使用double

答案 1 :(得分:0)

是的,你需要理解双指针。

如果您知道将从函数返回多少个浮点数

/*
    we know foo always returns N values
*/
void foo(float *ret, int N)
{
    int i;
    for(i=0;i<N;i++)
      ret[i] = ((float)i)/N;
}

if we don't know

/*
    return a list of numbers of random length
*/
void foo(float **ret, int *Nret)
{
   int N = rand() % 100;
   float *answer = malloc(N * sizeof(float));
   for(i=0;i<N;i++)
     answer[i] = ((float)i)/N;
   *ret = answer;
   *Nret = N;
}