UnreachableCode
UnreachableCode

Reputation: 1789

Can a 2D array be initialised this way?

/* Initialize matrix with values from 0 to N*N.  */
void
init_matrix_seq (unsigned N, float * m)
{
    unsigned i;

    for (i = 0; i < N*N; ++i)
        m[i] = (float) i;
}

I mean, it looks like one loop is being used to go through N*N elements in one dimension. Is this possible in C, without the need for another loop to cycle through columns?

EDIT:

Code which initialises the 2D arrays and calls this function is shown here:

  A = (float *) malloc (N * N * sizeof (float));
  B = (float *) malloc (N * N * sizeof (float));

  init_matrix (N, A, 1.0);
  init_matrix (N, B, 1.0);

Upvotes: 0

Views: 109

Answers (4)

Ramy Al Zuhouri
Ramy Al Zuhouri

Reputation: 21966

The answer is yes, but you can't use the double indexing and you could get issues if you want to index an element, instead of A[i][j] you have to call A[i*N+j].
If you want to do this using double indexes and having all adjacent in memory, then allocate the array this way:

float (*A) [N]= (float (*)[N] ) malloc(N*sizeof(float[N]) );

Now you have all adjacent in memory, you can use the function that you've written.But you can also use double indexing:

for(int i=0; i<N; i++)
    for(int j=0; j<N; j++)
        A[i][j]=i*N+j;

But your method is correct.

Upvotes: 2

WhozCraig
WhozCraig

Reputation: 66194

If all you want is to set them ALL to some initial value, then yes, use a single 1D indexing as such:

void init_matrix(unsigned N, float m[], float init_val)
{
    unsigned i;
    for (i = 0; i < N*N; ++i)
        m[i] = init_val;
}

Your sequential initialization would be exactly as you have it in your question:

void init_matrix_seq(unsigned N, float m[])
{
    unsigned i;
    for (i = 0; i < N*N; ++i)
        m[i] = i;
}

If you have specific values that need to hit positions m[i][j] then in C you can access by formal row-width by:

void init_matrix_seq (unsigned N, float m[][N])
{
    unsigned i,j;

    for (i = 0; i < N; ++i)
        for (j = 0; j < N; ++j)
        {
            m[i][j] = i*j; // <<your initial value here>>;
        }
}

If you want to access it as a single linear array you certainly can. The following accomplishes the same result as above (with the same assumption this is N*N floats wide).

void init_matrix_seq (unsigned N, float m[])
{
    unsigned i,j;

    for (i = 0; i < N; ++i)
        for (j = 0; j < N; ++j)
        {
            m[i*N+j] = i*j; // <<your initial value here>>;
        }
}

The latter example has the nicety of working in C and C++, the former will only work in C (last I checked, anyway).

Upvotes: 2

Viswesn
Viswesn

Reputation: 4880

This sample program tell you the way of using 1D array as 2D array

#include <stdio.h>
#define rows 4
#define cols 6

int main()
{
    int array1D[rows * cols] = 
         { 1, 2, 3, 4, 5, 6,
           7, 8, 9, 10, 11, 12,
           13, 14, 15, 16, 17, 18,
           19, 20, 21, 22, 23, 24 };

    int (*array2D)[cols] = (int (*)[cols]) array1D;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d ", array2D[i][j] );
        }
        printf("\n");
    }
 }

Upvotes: 0

user1697490
user1697490

Reputation:

You are correct; m is a one-dimensional array. Sometimes, people will use a 1D array in place of a 2D array (for the slight speed boost) by assigning each row to a section of the 1D array. I would not recommend doing this, because it hurts readability and the speed increase is less than trivial.

Upvotes: 0

Related Questions