This is your code (just formatted and added a missing closing brace):
#include <stdio.h>
mat(int n, int a[][5], b[][5] )
{
int i, c[5][5];
for(i=0; i<5; i++) {
for(j=0; j<5; j++) {
c[i][j] = a[i][j] + b[i][j];
}
return c;
}
}
I compile with:
$ gcc -std=c99 -Wall -Wextra -Wpedantic -Wconversion -Wno-sign-compare -Wshadow test.c -o test
and first thing I get is:
test.c:3:24: error: unknown type name ‘b’
mat(int n, int a[][5], b[][5] )
Let's fix that (add int
before b
and j
):
#include <stdio.h>
mat(int n, int a[][5], int b[][5] )
{
int i, c[5][5];
for(i=0; i<5; i++) {
for(int j=0; j<5; j++) {
c[i][j] = a[i][j] + b[i][j];
}
return c;
}
}
Now we get:
test.c:3:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
mat(int n, int a[][5], int b[][5] )
^
test.c: In function ‘mat’:
test.c:11:10: warning: return makes integer from pointer without a cast [-Wint-conversion]
return c;
^
test.c:11:10: warning: function returns address of local variable [-Wreturn-local-addr]
test.c:3:9: warning: unused parameter ‘n’ [-Wunused-parameter]
mat(int n, int a[][5], int b[][5] )
^
test.c:13:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
So what to we get:
mat()
returns int
because it's a default fallback that dates to before C99, but no is not standard anymore. It seems though, that you are compiling on Visual Studio which basically implements C89 + some C99 for C++ compatibility -- but still, fix it.
- Then you return
c
, which is definitely not of type int
.
- Also you don't use
n
, I guess it's meant to be the number of rows?
- You return after the first inner loop is done -- that's probably not wanted.
What to do instead:
Generally you usually want the caller to give space for the result, as you return c
which is local to mat()
it is undefined behavior what happens after mat()
finishes. Instead use the following declaration for mat()
:
void mat(int r, int c, int m1[r][c], int m2[r][c], int mr[r][c]);
where r
is rows, c
is columns, m1
, m2
are the input matrices, mr
is the result matrix.
The code would then be:
void mat(int r, int c, int m1[r][c], int m2[r][c], int mr[r][c])
{
for(int i = 0; i < r; i++) {
for(int j = 0; j < c; j++) {
mr[i][j] = m1[i][j] + m2[i][j];
}
}
}
You do not need to return anything -- you write to an object the caller provided (hopefully). If you feel brave you can check for m1 == NULL || m2 == NULL || mr == NULL
before.
Let's see how this works using this test code:
void print_mat(int r, int c, int m[r][c]);
int main() {
int m1[2][5] = {
{0,1,2,3,4},
{1,2,3,4,5}
};
int m2[2][5] = {
{10,11,12,13,14},
{11,12,13,14,15}
};
printf("printing matrix m1:\n");
print_mat(2,5,m1);
printf("printing matrix m1:\n");
print_mat(2,5,m2);
int c[2][5];
mat(2,5,m1,m2,c);
printf("printing matrix m1+m2:\n");
print_mat(2,5,c);
}
void print_mat(int r, int c, int m[r][c])
{
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("\t%d", m[i][j]);
}
printf("\n");
}
return;
}
I get:
printing matrix m1:
0 1 2 3 4
1 2 3 4 5
printing matrix m1:
10 11 12 13 14
11 12 13 14 15
printing matrix m1+m2:
10 12 14 16 18
12 14 16 18 20
which is exactly what it's supposed to be.
In the end:
- State the types specifically, it helps.
- Turn on all warnings if you are unsure.
- Usually don't acquire memory in a subfunction, let the caller do this.
- If you are unsure with pointers/arrays, try to avoid them and write small understandable test-cases; do research!