1

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);
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
John Boe
  • 3,501
  • 10
  • 37
  • 71

3 Answers3

1

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)
dbush
  • 205,898
  • 23
  • 218
  • 273
  • Thank you very much. The solution looks simple but it was tricky, I would not find out without your help. – John Boe Jul 28 '17 at 19:26
  • @user1141649 Something else I noticed: the inner loop isn't necessary since you're not looping through the second set of elements. You could move the assignment of `item` into the upper loop. – dbush Jul 28 '17 at 19:27
  • OK, but I needed this code only for temporal purposes when I wanted to export some data. When the data are exported I will not use it anymore (I've finished). But I can use the foreach macro later. – John Boe Jul 28 '17 at 22:34
0

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
John Bollinger
  • 160,171
  • 8
  • 81
  • 157
0

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}