定义矩阵并将其传递给C中的函数

时间:2009-08-14 07:33:31

标签: c matrix

我想创建一个程序,我可以使用指针将矩阵传递给函数。 我初始化并扫描了void main()中的2个矩阵,然后我尝试将它们传递给void add函数。我认为我在声明和调用函数的语法中出错了。我指定了一个指向矩阵基址的指针。 (例如:int *x=a[0][0], *y=b[0][0])。什么是正确的声明?如何指定尺寸?

3 个答案:

答案 0 :(得分:2)

这样的事情应该可以解决问题。

#define COLS 3
#define ROWS 2

/* Store sum of matrix a and b in a */
void add(int a[][COLS], int b[][COLS])
{
    int i, j;

    for (i = 0; i < ROWS; i++)
        for (j = 0; j < COLS; j++)
            a[i][j] += b[i][j];
}

int main()
{
    int a[ROWS][COLS] = { { 5, 10, 5} , { 6, 4, 2 } };
    int b[ROWS][COLS] = { { 2, 3, 4} , { 10, 11, 12 } };

    add(a, b);

    return 0;
}

编辑:除非您想在运行时指定尺寸,否则您必须使用平面阵列并自行执行2D阵列算法:

/* Store sum of matrix a and b in a */
void add(int rows, int cols, int a[], int b[])
{
    int i, j;

    for (i = 0; i < rows; i++)
        for (j = 0; j < cols; j++)
            a[i * cols + j] += b[i * cols + j];
}

答案 1 :(得分:1)

给定一个二维数组

T a[N][M];

指向该数组的指针看起来像

T (*ap)[M];

所以你的添加函数原型应该看起来像

void add(int (*a)[COLS], int (*b)[COLS]) {...}

并被称为

int main(void)
{
  int a[ROWS][COLS];
  int b[ROWS][COLS];
  ...
  add(a, b);

但是,此代码突出了几个问题。首先,您的添加功能依赖于未通过参数列表传递的信息,而是通过全局变量或符号常量;即,行数(在参数类型中明确提供列数)。这将add函数与此特定程序紧密耦合,并使其难以在其他地方重用。出于您的目的,这可能不是问题,但通常您只希望您的函数通过参数列表和返回值与其调用者进行通信。

第二个问题是,如上所述,您的函数仅适用于ROWS行和COLS列的矩阵;如果你想在同一个程序中添加不同大小的矩阵,这种方法是行不通的。理想情况下,您需要一个可以处理不同大小矩阵的add函数,这意味着您需要将大小作为单独的参数传递。这也意味着我们必须改变传入的指针的类型。

一种可能的解决方案是将矩阵视为int的简单指针并手动计算偏移量而不是使用下标:

void add (int *a, int *b, size_t rows, size_t cols)
{
  size_t i;
  for (i = 0; i < rows; i++)
  {
    size_t j;
    for (j = 0; j < cols; j++)
    {
      *(a + cols * i + j) += *(b + cols * i + j);
    }
  }
}

并称之为:

int main(void)
{
  int a[ROWS][COLS] = {...};
  int b[ROWS][COLS] = {...};
  int c[ROWS2][COLS2] = {...};
  int d[ROWS2][COLS2] = {...};
  ...
  add(a[0], b[0], ROWS, COLS);
  add(c[0], d[0], ROWS2, COLS2);
  ...
}

a [0]和b [0]的类型是“int的COLS元素数组”;在这种情况下,它们都将被隐式转换为“指向int的指针”。类似地,c [0]和d [0]也被隐式转换为int *。 add()函数中的偏移量有效,因为2D数组是连续的。

编辑我刚刚意识到我正在回应caf的例子,而不是OP,并且caf编辑了他的回复以显示与我的例子非常相似的内容。 C'est la guerre。我将留下我的例子,只是为了表明一种略微不同的方法。我还认为在函数和调用者之间传递信息的措辞是有价值的。

答案 2 :(得分:0)

@caf已经展示了一个很好的代码示例。

我想指出:

  

我指定了一个指向基地的指针   我的矩阵的地址。 (例如:int   * X = A [0] [0],* Y = B [0] [0])。

您没有指定指向矩阵底部的指针。这样做分配给x和y指向的值,分别是a和b中的基值。

正确的方法是

int  (*x)[] = a;
int  (*y)[] = b;

或者

int *x = &a[0][0];
int *y = &b[0][0];