David542
David542

Reputation: 110452

Iterating an MDA in C

Is the following a common pattern for going through a multi-dimensional array in C?

int coordinates[3][2] =  {
    {0,0},
    {2,2},
    {5,5}
};

size_t array_size = sizeof(coordinates)/sizeof(coordinates[0]);
size_t element_size = sizeof(coordinates[0]) / sizeof(coordinates[0][0]);

// full element at position array[i] (coordinates hardcoded)
for (int i=0 ; i < array_size ; i++) {
    printf("The coordinate at index %d is (%d, %d)\n", i, coordinates[i][0], coordinates[i][1]);

    // inner element at position array[i][j]
    for (int j=0; j < element_size; j++) {
        printf("The %c value at coordinate (%d, %d) is %d\n", (j==0)?'x':'y', coordinates[i][0], coordinates[i][1], coordinates[i][j]);
    }
}

Are there other patterns that are used to do these iterations, or is the element sized usually gathered with:

sizeof(array) / sizeof(array[0]);
sizeof(array[0]) / sizeof(array[0][0]);
sizeof(array[0][0]) / sizeof(array[0][0][0]);
...etc...

Upvotes: 0

Views: 43

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754800

What you outline isn't particularly common, at least, not the method of calculating the number of columns. The method of calculating the number of rows is common-place when the circumstances are right (the array definition is visible and is not a function argument).

You have:

int coordinates[3][2] = { … };

size_t array_size = sizeof(coordinates)/sizeof(coordinates[0]);
size_t element_size = sizeof(coordinates[0]) / sizeof(coordinates[0][0]);

When the number of rows and columns is fixed as shown, it is probably more usual to use named constants (#define or enum — see static const vs #define vs enum for more on the differences):

enum { NUM_ROWS = 3, NUM_COLS = 2 };
int coordinates[NUM_ROWS][NUM_COLS] = { … };

The loops would then use those constants as the bounds:

for (int r = 0; r < NUM_ROWS; r++)
{
    for (int c = 0; c < NUM_COLS; c++)
    {
        …
    }
}

If you don't know the number of rows, then you can use the sizeof(array) / sizeof(array[0]) idiom:

int coordinates[][NUM_COLS] = { … };
enum { NUM_ROWS = sizeof(coordinates) / sizeof(coordinates[0]) };

and then proceed using the limits as before.

With modern C, in a function where the array is passed to the function, you can use:

void function(size_t nrows, size_t ncols, int coordinates[nrows][ncols])
{
    for (size_t r = 0; r < nrows; r++)
    {
        for (size_t c = 0; c < ncols; c++)
        {
            …
        }
    }
}

This is using VLA (variable length array) notation, a part of C99.

If you have more dimensions to the array, you have to decide on names for the dimensions other than rows and columns (do they come before or after the rows and columns?), and you then write the code making the appropriate use of those names. In my work, 2D arrays are as complex as I usually need, so 'rows and cols' works well.

Note that the compiler will only determine the dimension of the first subscript (rows in a 2D array) from the initializers; the sizes of the other dimensions must be specified when the array is defined.

You can use a macro for the size, such as:

#define DIM(x)    (sizeof(x) / sizeof((x)[0]))

This only works on arrays defined locally (automatic arrays or static arrays) or defined at file scope (static or global — no storage class modifier). It does not work on arrays in parameter lists to functions. There are numerous alternative names for a macro like this. Microsoft provides _countof to provide a count of the elements in an array; it is essentially equivalent to DIM.

Upvotes: 1

Related Questions