我读过关于C中指针的理论,但我只是心中有困惑。
想象一下,我调用一个方法,它必须使用指针返回一个浮点数组(而不是return语句)。
第一点:我方法的负责人必须这样:myMet([somearguments], float* myvector)
?
第二点:是否建议在我方法的主体中创建另一个数组,填充它然后执行
*myvector = thatarray
?
我很遗憾地提出这样一个基本问题,但C中的指针似乎对我很不友好
答案 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;
}