Define a matrix and pass it to a function in C

柔情痞子 提交于 2019-12-23 05:14:37

问题


I want to create a program in which I can pass a matrix to a function using pointers. I initialized and scanned 2 matrices in the void main() and then I tried to pass them to a void add function. I think I am going wrong in the syntax of declaration and calling of the function. I assigned a pointer to the base address of my matrix. (for eg: int *x=a[0][0], *y=b[0][0]). What is the right declaration? How can I specify the dimensions?


回答1:


Something like this should do the trick.

#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;
}

EDIT: Unless you want to specify the dimensions at runtime, in which case you have to use a flat array and do the 2D array arithmetic yourself:

/* 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];
}



回答2:


Given a 2D array of

T a[N][M];

a pointer to that array would look like

T (*ap)[M];

so your add function prototype should look like

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

and be called as

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

However, this code highlights several problems. First is that your add function is relying on information not passed via the parameter list, but via a global variable or symbolic constant; namely, the number of rows (the number of columns is explicitly provided in the type of the parameters). This tightly couples the add function to this specific program, and makes it hard to reuse elsewhere. For your purposes this may not be a problem, but in general you only want your functions to communicate with their callers through the parameter list and return values.

The second problem is that as written, your function will only work for matrices of ROWS rows and COLS columns; if you want to add matrices of different sizes within the same program, this approach will not work. Ideally you want an add function that can deal with matrices of different sizes, meaning you need to pass the sizes in as separate parameters. It also means we must change the type of the pointer that we pass in.

One possible solution is to treat your matrices as simple pointers to int and manually compute the offsets instead of using subscripts:

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);
    }
  }
}

and call it like so:

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);
  ...
}

The types of a[0] and b[0] are "COLS-element arrays of int"; in this context, they'll both be implicitly converted to "pointer to int". Similarly, c[0] and d[0] are also implicitly converted to int *. The offsets in the add() function work because 2D arrays are contiguous.

EDIT I just realized I was responding to caf's example, not the OP, and caf edited his response to show something very similar to my example. C'est la guerre. I'll leave my example as is just to show a slightly different approach. I also think the verbiage about passing information between functions and callers is valuable.




回答3:


@caf has shown a good code example.

I'd like to point out that:

I assigned a pointer to the base address of my matrix. (for eg: int *x=a[0][0],*y=b[0][0]).

You are not assining a pointer to the base of the matrix. What this does is assign to the value pointed by x and y, the base value in a and b respectively.

The right way would be

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

or alternatively

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


来源:https://stackoverflow.com/questions/1276520/define-a-matrix-and-pass-it-to-a-function-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!