tags:

views:

572

answers:

3

Hello, I want to create a program wherein 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]). Pls help me in developing this program.

A: 

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];
}
caf
thank you !! I really appreciate it !!! but according to this i can't get the order of matrix from the user ?? it has to be defined ?
You can have the matrix dimensions specified at runtime, but then you lose the ability to have the compiler index the array for you. I've updated my answer with an example of this.
caf
A: 

@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];
Tom
@ neil butterworth - I am using C language and i have no knowledge of C++@ others- I am new to programming . I have been given an assignment wherein i have to accept 2 matrices and perform add,transpose,multiplication on them and find saddle point if any.i tried to pass those matrices to their respective functions using pointers. here is my attempt at doing so -
#include<stdio.h>#include<conio.h>void add();void transpose(int *,int,int);void multiply();void saddlept();void main(){ int a[10],b[10],i,j,r,c,p,q,n,*x= clrscr(); printf("enter the order of matrix a"); scanf("%d%d", printf("enter the elements of matrix a row-wise"); for(i=0;i<r;i++) { for(j=0;j<c;j++) { scanf("%d", } } printf("enter the order of matrix b"); scanf("%d%d", printf("enter the elements of matrix a row-wise"); for(i=0;i<p;i++) { for(j=0;j<q;j++) { scanf("%d", } }
printf("enter your choice:\n1:add\n2:transpose\n3:multiply\n4:saddle point\n5:exit"); scanf("%d", switch(n) { case 1: add(a[10][10],b[10][10],c[10][10]); break; case 2: transpose(x,r,c); transpose(y,p,q); break; case 3: multiply(a[10][10],b[10][10],c[10][10]); break; case 4: saddlept(a[10][10]); saddlept(b[10][10]); break; case 5: break; } getch();}
void transpose(int *k,int l,int m){ if(l==m) { for(i=0,j=0;i<l,j<m;i++,j++) { *k=a[j][i]; *k++; } printf("the transpose of the matrix is "); for(i=0;i<l;i++) { printf("\n"); for(j=0;j<m;j++) { printf("%d\t",*k); } } } else printf("transpose is not possible");}
caf
The types of a and b decay to int (*)[COLS], not int **; you'll get a warning for incompatible pointer types. Remember that in most contexts, a variable of type "N-element array of T" is implicitly converted to type "pointer to T" and the value is set to the address of the first element in the array. If the type of a is "ROWS-element array of COLS-element array of int", then the converted type is "pointer to COLS-element array of int".
John Bode
John is completely correct, and further the `int (*)[COLS]` value is a pointer to the start of the array, so dereferencing the `int **` won't even work. `int (*x)[COLS] = a` is OK.
caf
@caf, John, thanks for your comments, ive edited my code.
Tom
A: 

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.

John Bode