2

I'm trying to loop through an array of structs in reverse, not quite sure how to go about it. This is how I'm looping through normally:

    struct Thing* ptr = things;
    struct Thing* endPtr = things + sizeof(things)/sizeof(things[0]);

    for(ptr < endPtr)
    {
        // do stuff
    }
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • What is `things`? And why not use a loop using the *indexes* instead? – Some programmer dude Nov 11 '16 at 09:38
  • 1
    `ptr[(sizeof(things)/sizeof(things[0]))-1]` is the last element, so starting from that one down to 0 index... – LPs Nov 11 '16 at 09:39
  • 1
    "`for`".... the new "`while`". – WhozCraig Nov 11 '16 at 09:43
  • @WhozCraig `#define for while`. Works like a charm. And it also allows me to do `do {...} for (ptr < endPtr);` :) – Lundin Nov 11 '16 at 14:56
  • obscuring the code by eliminating the normal usage of the `for` statement is a very bad idea. As it is, the posted code does not compile and this line: `struct Thing* endPtr = things + sizeof(things)/sizeof(things[0]);` yields a pointer to just past the end of the array rather than a pointer to the last element – user3629249 Nov 12 '16 at 18:42

3 Answers3

2

Assuming N >= 0, the item-magnitude of your things sequence , you can use indexes, of course, but really you simply need a single pointer:

struct Thing *ptr = things + N;
while (ptr != things)
{
    --ptr;

    // do something with *ptr;
}
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • @IanAbbott technically, you can't shorten this using a post-decrement in the while-expression. I've asked only two questions on SO, [one of them directly relating to that very subject.](https://stackoverflow.com/questions/30512669/does-applying-post-decrement-on-a-pointer-already-addressing-the-base-of-an-arra) Hard as it is to fathom, the final decrement actually invokes UB. I chose the code in this post for that very reason. – WhozCraig Nov 11 '16 at 10:36
  • Yes, I realized my mistake just after posting my comment and deleted it. (For reference, I suggested post-decrementing `ptr` in the test: `while (ptr-- != things)`. The problem with that is the final decrement leaves `ptr` less than `things`, which is UB, as mentioned by WhozCraig.) – Ian Abbott Nov 11 '16 at 10:39
  • @IanAbbott I'm pretty sure `while (ptr != things && --ptr)` *would* work, however, since the decrement would be skipped on the short circuit eval. It would, however, be oddly cryptic to anyone reviewing the code. – WhozCraig Nov 11 '16 at 10:44
  • @WhozCraig Interesting, I just recently asked a similar `++` [question](http://stackoverflow.com/q/40537682/2410359) to your `--` [post](https://stackoverflow.com/questions/30512669/does-applying-post-decrement-on-a-pointer-already-addressing-the-base-of-an-arra). – chux - Reinstate Monica Nov 11 '16 at 14:46
0

This can be a possible solution

 // assuming 'Thing' is the structure in question and 'size' is the length of array
struct Thing array[size];   // created an array of structure Thing having length equals size

struct Thing *ptr;  // pointer of type struct Thing 
ptr = array;
ptr = ptr + (size-1); // point the pointer to last element of the array
int i; //counter

for( i=0; i < size; i++ )
{
    // do something with the pointer ptr
    ptr--; 
}
  • Your `ptr = ptr + ...` invokes undefined behavior. `ptr` is indeterminate when its value is taken with the right side expression of that assignment. And the size computation is wrong anyway. Pointer arithmetic strides to the size of the pointed-to object type already. – WhozCraig Nov 11 '16 at 10:39
  • `ptr` should initialized before using. You program results in UB. – babon Nov 11 '16 at 12:32
0

It is possible to use pointers in a down-counting loop, but I would instead prioritize readability:

size_t size = sizeof(things) / sizeof(things[0]);

for(size_t i=0; i<size; i++)
{
  size_t index = size - i - 1;
  things[index] = something;
}
Lundin
  • 195,001
  • 40
  • 254
  • 396