C中的向量和矩阵

时间:2014-03-23 21:47:22

标签: c vector return

我想在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]仅调用向量的一个分量时,不会发生此错误。

你能帮我解决这个问题吗?

提前谢谢。

4 个答案:

答案 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脚本可以为任意大小的矩阵生成代码。如果你需要,请发表评论。