我想在C中执行矢量运算,但我不知道如何从函数返回矢量。我试图以这种方式生成一个向量:
float *generate_vector()
{
static float vec[3];
return vec;
}
但是,使用
调用此函数int main (void)
{
float vec[3];
vec = generate_vector();
}
导致错误(错误:从类型'float *'指定类型'float [3]'时不兼容的类型)。有趣的是,当使用vec [1] =& generate_vector()[1]仅调用向量的一个分量时,不会发生此错误。
你能帮我解决这个问题吗?
提前谢谢。
答案 0 :(得分:1)
这里有两个问题,第一个是你不能像这样分配一个数组:
vec = generate_vector();
当数组在它们通过时会衰减到指针,但是在它声明它是一个数组的函数中,你不能像这样指定它。< / p>
您需要声明一个指针来获取返回的数组:
float *vec = generate_vector();
仅供参考,您可能感兴趣的第二个选项,如果您想从此功能生成新数组,您可以动态地执行此操作。
float *vec = malloc(3 * sizeof(float));
然后你需要在以后完成这项任务。
答案 1 :(得分:1)
如果你愿意,这是一种不同的方法。效率稍低但可能更容易理解(并且在复杂程序中可能更容易处理)。
在C中,您无法返回数组。您需要malloc()
一个缓冲区(您需要跟踪它以及稍后free()
它)或者您需要在函数外部声明一个“返回数组”并将一个额外的指针传递给您功能
因此无法返回数组。但是,嘿,这是一个很好的解决方法:你实际上可以返回包含数组的struct
:
#include <stdio.h>
struct vec
{
double v[3];
};
struct vec multiply_scalar(struct vec v, double scalar)
{
int i;
struct vec ret;
for (i = 0; i < 3; i++)
{
ret.v[i] = v.v[i] * scalar;
}
return ret;
}
答案 2 :(得分:0)
如上所述,您返回一个指针,因此您需要将其指定给指针变量。另外,使用像这样的静态数组是一个坏主意。最好采用这样的矢量:
void generate_vector(float * inVector)
这样,内存管理在函数之外处理,你不会在多个地方意外使用相同的向量。
通过您的设置,该功能的用户可以编写此代码:
float * vectorA = generate_vector();
float * vectorB = generate_vector();
他们可能不期望vectorA和vectorB实际上是同一个东西,这会导致错误。
答案 3 :(得分:0)
在C中执行这些操作时,我倾向于为函数成功或失败的指示器保留函数的返回值。我倾向于传递输入和输出数组作为参数。
几年前,我编写了一个Perl脚本来生成循环展开的矩阵和向量代码。 (与C ++模板类似,但对于C)输出的一个示例是使用矩阵变换向量的函数。
/* Multiplies a matrix with a vector */
extern void mat_xform3(double m[3][3], double v[3], double mv[3]);
实现:
#ifndef NULL
#define NULL (void*)0
#endif
/* If the product of the multiplication of two doubles is less than EPS,
* the value is set to 0. */
#define EPS 1e-8
void mat_mul3(double a[3][3], double b[3][3], double ab[3][3])
{
double res[3][3];
assert(a!=NULL); assert(b!=NULL); assert(ab!=NULL);
res[0][0] = a[0][0]*b[0][0];
res[0][0] += a[0][1]*b[1][0];
res[0][0] += a[0][2]*b[2][0];
if (res[0][0] < EPS && res[0][0] > -EPS) {res[0][0] = 0.0;}
res[0][1] = a[0][0]*b[0][1];
res[0][1] += a[0][1]*b[1][1];
res[0][1] += a[0][2]*b[2][1];
if (res[0][1] < EPS && res[0][1] > -EPS) {res[0][1] = 0.0;}
res[0][2] = a[0][0]*b[0][2];
res[0][2] += a[0][1]*b[1][2];
res[0][2] += a[0][2]*b[2][2];
if (res[0][2] < EPS && res[0][2] > -EPS) {res[0][2] = 0.0;}
res[1][0] = a[1][0]*b[0][0];
res[1][0] += a[1][1]*b[1][0];
res[1][0] += a[1][2]*b[2][0];
if (res[1][0] < EPS && res[1][0] > -EPS) {res[1][0] = 0.0;}
res[1][1] = a[1][0]*b[0][1];
res[1][1] += a[1][1]*b[1][1];
res[1][1] += a[1][2]*b[2][1];
if (res[1][1] < EPS && res[1][1] > -EPS) {res[1][1] = 0.0;}
res[1][2] = a[1][0]*b[0][2];
res[1][2] += a[1][1]*b[1][2];
res[1][2] += a[1][2]*b[2][2];
if (res[1][2] < EPS && res[1][2] > -EPS) {res[1][2] = 0.0;}
res[2][0] = a[2][0]*b[0][0];
res[2][0] += a[2][1]*b[1][0];
res[2][0] += a[2][2]*b[2][0];
if (res[2][0] < EPS && res[2][0] > -EPS) {res[2][0] = 0.0;}
res[2][1] = a[2][0]*b[0][1];
res[2][1] += a[2][1]*b[1][1];
res[2][1] += a[2][2]*b[2][1];
if (res[2][1] < EPS && res[2][1] > -EPS) {res[2][1] = 0.0;}
res[2][2] = a[2][0]*b[0][2];
res[2][2] += a[2][1]*b[1][2];
res[2][2] += a[2][2]*b[2][2];
if (res[2][2] < EPS && res[2][2] > -EPS) {res[2][2] = 0.0;}
memcpy(ab, res, 3*3*sizeof(double));
}
在这种情况下,函数不会失败,因此返回void
。但是一个例如反转矩阵可以失败,以便返回一个表示成功或失败的值。
Perl脚本可以为任意大小的矩阵生成代码。如果你需要,请发表评论。