2

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)?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 3
    The first function prototype is correct, but the way you call the function `minimum(10, x[][10])` is not syntactically correct. Can you provide more context? Like a self-contained small program. – DeiDei Dec 31 '16 at 17:28
  • 1
    The first function prototype should work with C99. When you call the function, just pass `x` where `x` is an array that you have defined as `int x[10][10]`. (The number of rows may vary, but the number of columns must be cosistent with the `size` you pass.) – M Oehm Dec 31 '16 at 17:29
  • @MarošČergeť: Please don't post long code fragments as comments; edit and update your question instead. – M Oehm Dec 31 '16 at 17:35
  • Yeah thanks, I realised it then when I posted it. This is my very first post here. – Maroš Čergeť Dec 31 '16 at 17:41

3 Answers3

5

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)

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
user2736738
  • 30,591
  • 5
  • 42
  • 56
3

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 );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

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

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 1
    `w * h * sizeof(double)` --> `sizeof(double) * w * h` would help guard against unwelcome overflow (or `unsigned` wraparound, rather) by forcing `size_t` arithmetic. – ad absurdum Dec 15 '18 at 19:57