I've declared my function where I want to find the minimum from diagonals [0][0] ... [5][5] and [0][5]... [5][0].
I have the algorithm but my problem is with the actual function header.
I have problem with creating the formal arguments for the function.
I know that we have to pass at least x[][this]
size of array to the function, but I tried various combinations, even
double minimum(int size, double x[][size]){...}
double minimum(double x[][int size]){...}
The first case gives an error when calling:
minimum(10, x[][10])
error: expected expression before ']' token `
The second case gives an error in declaration of function:
error: expected expression before 'int'
Can someone tell what the problem is (or problems are)?
double minimum(int rowsize,int size, double x[rowsize][size]){...}
or simply
double minimum(int rowsize,int size, double x[][size]){...}
So specifying rowsize
is optional.
But here I guess it is square size x size
so it will be
double minimum(int size, double x[][size]){...}
So you are correct in that.
How to call it?
minimum(10,x)
If you are dealing with an array of the fixed size 5 then you can declare the function like
double minimum( double x[][5] );
and call it like
minimum( x );
If the size of the array can be changed you can use variable length arrays and declare the function like
double minimum( size_t n, double x[][n] );
of for self-documentation like
double minimum( size_t n, double x[n][n] );
The function can be called like
minimum( 10, x );
or like
minimum( sizeof( x ) / sizeof( *x ), x );
You could use a previous formal argument as the dimension for a later formal argument of a C99 function, see this question.
So the following code is valid:
double
sum (int w, int l, double mat[w][l])
{
double s = 0.0;
for (int i = 0; i < w; i++)
for (int j = 0; j < l; j++)
s += mat[i][j];
return s;
}
If you have declared
double t[5][7];
You can call
double s = sum(5,7,t);
However, you might not want that. A possibility could be to represent a matrix (abstract data type) as a pointer to a struct
ending with a flexible array member:
struct matrix_st {
unsigned w;
unsigned h;
double m[]; // conventionally w*h double numbers
};
You could allocate it with
struct matrix_st *make_matrix (unsigned w, unsigned h)
{
// we might check that w and h are of reasonable size....
// to avoid arithmetic overflow, or excessive memory allocation.
struct matrix_st* pm = malloc(sizeof(struct matrix_st) + sizeof(double)*w*h);
if (!pm) return NULL; // malloc failure
pm->w = w;
pm->h = h;
for (long i=w*h-1; i>=0; i--) pm->m[i] = 0.0;
return pm;
};
for example
struct matrix_st* mat = make_matrix(5,7);
and when you are finished, just call free(mat);
(preferably followed by mat = NULL;
).
You could code the function accessing it as:
inline double matrix_access(struct matrix_st*pm, unsigned i, unsigned j)
{
assert (pm != NULL);
assert (i < pm->w);
assert (j < pm->h);
return pm->m[i*pm->w+j];
}
(practically speaking, since that function is inline
, it can run really fast, nearly as fast as other solutions or answers to your question)
I leave to the reader the exercise of coding other matrix functions (including modification of an element of the matrix, the equivalent of sum
, etc...).