0

if R is my rows number and C my column number I initialize a pointer like this:

int * a = (int*) malloc(R*C*sizeof(int));

Then to access the second element in the second row I type:

a[1*c + 1]

I want to emulate a 2D arr.

How can I make a macro that will convert this: a[i][j] to this a[i*c + j]?

12
  • 2
    Why not use a 2D array, but an unsafe hack instead? Commented Feb 14, 2017 at 19:11
  • 1
    Macros take comma separated arguments, they can't do general syntax conversion Commented Feb 14, 2017 at 19:11
  • 3
    Use this #define a(i,j) a[(i)*c+(j)] but I don't think it will be useful using the original one is much more safer and readable Commented Feb 14, 2017 at 19:12
  • 2
    @Sabrina so what about a(1+3, 4) Commented Feb 14, 2017 at 19:12
  • 1
    The question in itself makes non sense to me. Commented Feb 14, 2017 at 19:20

3 Answers 3

2

A macro can't read and convert square brackets. But you can write:

int (*b)[C] = (void *)a;

and then you can use b[i][j] which has the same meaning as a[i*C + j].

Sign up to request clarification or add additional context in comments.

Comments

0

If you don't want a separate macro for every dynamic array that you might use, you will need something a bit more general. For example:

#define INDEX_2D(array, i, j, j_sz) array[ (i) * (j_sz) + (j) ]

Then you can use it like this:

INDEX_2D(my_array, row, col, C) = x;
printf("%d\n", INDEX_2D(my_array, row, col, C));

Still, this seems clumsy. If you can't use actual 2d arrays, why not just use straightforward indexing calculations, which actually seem more clear?

my_array[row * C + col] = x;
printf("%d\n", my_array[row * C + col]);

3 Comments

The last suggestion is best. Indexing the array directly is shorter than the macro version, only 1 effective character more than the 2D equivalent my_array[row][col] but above all it is clear and easy to read. As with a newbie function that adds or compares two integers, the macro is only of use until you become accustomed to taking the inline syntax in your stride.
@WeatherVane-- agreed. I hope my answer did not come across as suggesting that using a macro is in any way a good idea for this. I had hoped that it would instead illustrate the clumsy nature of a general macro solution here.
No, the answer led to that conclusion, having offered a solution, hence my UV.
0

The preprocessor is not a good tool for faking 2D array access on a 1D array. Another approach would be to create an array of pointers into the 1D array, like so:

int *a = malloc( R * C * sizeof *a ); // do not cast the result of malloc!
int *b[] = { &a[0], &a[C], &a[2*C], ..., &a[(R-1) * C] };

The result is something like the following (assume R == 2 and C == 3):

   +---+                +---+
b: |   | b[0] -----> a: |   | a[0]
   +---+                +---+
   |   | b[1] ---+      |   | a[1]
   +---+         |      +---+
                 |      |   | a[2]
                 |      +---+
                 +----> |   | a[3]
                        +---+
                        |   | a[4]
                        +---+
                        |   | a[5]
                        +---+

This way, you can use b[i][j] to access elements in a (b[i][j] == a[i * R + j]).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.