John Boe
John Boe

Reputation: 3611

How to implement foreach loop on multidimensional array in C?

I have found this macro here, where @Johannes Schaub used it to array. I tried to apply it to multidimensional array but I got warning:

initialization from incompatible pointer type [enabled by default]|

#define foreach(item, array) \
    for(int keep = 1, \
            count = 0,\
            size = sizeof (array) / sizeof *(array); \
        keep && count != size; \
        keep = !keep, count++) \
      for(item = (array) + count; keep; keep = !keep)

double DaysEarthSun[][10] = {
    //            0                                                         1                       2                       3                       4                       5                       6                       7                       8                       9
    //          JDTDB,            Calendar Date (TDB),                      X,                      Y,                      Z,                     VX,                     VY,                     VZ,                     LT,                     RG,                     RR,
    {2305447.500000000, /*"A.D. 1600-Jan-01 00:00:00.0000",*/ -2.568497981915648E-01,  9.438245451677045E-01,  6.410938668761658E-04, -1.684598702834566E-02, -4.667597482526307E-03, -4.906040833845624E-06,  5.649322014152373E-03,  9.781497849989120E-01, -8.026158042429985E-05},
    {2305448.500000000, /*"A.D. 1600-Jan-02 00:00:00.0000",*/ -2.736541829631095E-01,  9.390104932363517E-01,  6.360724040092633E-04, -1.676196451434489E-02, -4.960286450217222E-03, -5.142448255071298E-06,  5.648881285390255E-03,  9.780734751792867E-01, -7.236940265538736E-05}
};

void printSOE(){
    double distance, velocity, km, km_2, speed;
    FILE *f;
    foreach(int *soe,
                DaysEarthSun) {
        distance = sqrt( soe[1]*soe[1] + soe[2]*soe[2] + soe[3]*soe[3] ); // units: AU-D
        velocity = sqrt( soe[4]*soe[4] + soe[5]*soe[5] + soe[6]*soe[6] ); // units: AU-D
        km = (149597870.700*distance); // km/day
        speed = (149597870.700*velocity); // km/day
        km_2 = 25902068370*soe[7]; // E-S distance: light day to km
        printf("\n\n%f km , %f km/day\n", km, speed);
        printf("distance based on light: %f km/day\n\n", km_2);
        f = fopen("output.txt", "a");
        fprintf(f, "%f, %f,", km, speed );
    }
    fclose(f);
}

Upvotes: 1

Views: 323

Answers (3)

DR GamerGuy
DR GamerGuy

Reputation: 1

Here is an almost exact implementation of forEach: for(int i = 0; i < something; i++); as forEach in this case would be c#'s forEach(int I in something){//code here}

Upvotes: 0

dbush
dbush

Reputation: 223917

There's two errors here.

The first is that you have a type mismatch. You have int *soe but you are attempting to assign a double [] (which decays to a double *) to it. So change it to double *soe.

The second error is in the macro:

for(item = (array) + count; keep; keep = !keep)

It looks like you're attempting to assign an element of array to item, but that's not what's happening. You do pointer addition on the array, but fail to dereference it.

Either add the dereference:

for(item = *((array) + count); keep; keep = !keep)

Or use the array element operator:

for(item = (array)[count]; keep; keep = !keep)

Upvotes: 1

John Bollinger
John Bollinger

Reputation: 180201

Your macro looks suspicious -- I'm having trouble analyzing why it does some of the things it does. I strongly suggest that you abandon it and write your own iteration using a standard for construct.

Whether you continue to use the macro or not, however, you need to understand that C multidimensional arrays are arrays of arrays. A pointer to one element of a multidimensional array is therefore a pointer to an array. The type of such a pointer is different from the type of a pointer to the ultimate scalar type.

In particular, given

double DaysEarthSun[][10] = {
    // ...
};

, a pointer to an element of DaysEarthSun has type double (*)[10]. You would declare a variable of that type like so:

double (*soe)[10];  // RIGHT: pointer to array of 10 doubles

If you want to iterate through your array via pointers to its elements, that's the type of the pointer you need to use.

Note also that it's quite a different thing from

double *soe;        // WRONG: pointer to (one) double

and from

double *soe[10];    // WRONG: Array of 10 pointers to (one) double

Upvotes: 0

Related Questions