horus
horus

Reputation: 89

C flat array using matlab syntax

I'd like to use my own type matrix in C using a syntax matlab-like to access it. Is there a solution using the preprocessor? Thanks. (The following code doesn't work).

include <stdio.h>
#define array(i,j) array.p[i*array.nrows+j] //???????????

typedef struct
{
 unsigned int nrows;
 unsigned int ncols;
 float* p;
} matrix;

int main()
{
  unsigned int i=4,j=5;
  float v=154;
  matrix a;

  a.p=(float*) malloc(10*sizeof(float));

  array(i,j)=v;

return 0;
}

Upvotes: 0

Views: 107

Answers (3)

horus
horus

Reputation: 89

thank you for your help. I fixed some trivial errors in the initial code. I see your answers and I suppose that a matlab syntax cannot be implemented using a generic #define rule in the preprocessor for several structs. Instead, a #define rule must be written for each specific struct as the following code.

Thank you so much again.

#include <stdio.h>
#define a(i,j) a.p[i*a.nrows+j]

typedef struct
{
 unsigned int nrows;
 unsigned int ncols;
 float* p;
} matrix;

int main()
{
  unsigned int i=4,j=5;
  float v=154;
  matrix a;

  a.nrows=10;
  a.ncols=10;

  a.p=(float *) malloc(100*sizeof(float));

  a(i,j)=v;

  return 0;
}

Upvotes: 0

Mad Physicist
Mad Physicist

Reputation: 114310

You would have to pass in the name of your array to the macro, but yes, you could do something like that.

Just as an FYI, MATLAB order is more generally known as "column major". C order is more generally known as "row major order".

I have taken the liberty of correcting 1) your memory allocation and 2) your initialization of the dimensions since they are necessary for the macro to work properly:

include <stdio.h>

#define INDEX(mat, i, j) (mat).p[(i) * (mat).nrows + (j)]

typedef struct
{
    unsigned int nrows;
    unsigned int ncols;
    float *p;
} matrix;

int main()
{
    unsigned int i = 4, j = 5;
    float v = 154;
    matrix a = {i, j, NULL};

    a.p = malloc(i * j * sizeof(float));
    INDEX(a, i - 1, j - 1) = v;

    return 0;
}

Here the order is column major, but the index is still zero-based. I have highlighted this by accessing index [i - 1, j - 1] instead of [i, j]. If you want one-based indexing to really conform to MATLAB's way of doing things, you can change your macro to this:

#define INDEX(mat, i, j) (mat).p[((i) - 1) * (mat).nrows + (j) - 1]

Then in main, you could do:

INDEX(a, i, j) = v;

Upvotes: 3

Oo.oO
Oo.oO

Reputation: 13375

Maybe this approach could help you

#include <stdio.h>
#define array(arr,i,j) (arr.p[ i * arr.nrows + j ]) //???????????

typedef struct
{
 unsigned int nrows;
 unsigned int ncols;
 float* p;
} matrix;

int main()
{
  unsigned int i=4,j=5;
  float v=154;
  matrix a;

  a.p=(float*) malloc(10*sizeof(float));

  array(a,i,j)=v;

return 0;
}

If you will try to do: a(i,j) it will try to make a call to "a".

Upvotes: 0

Related Questions