chris edwards
chris edwards

Reputation: 1442

C why is this for loop not executing when its conditions are met?

I have a for loop which is used to find the nearest helicopter to a specific ship in danger.

The problem I am having is I need to ignore LifeBoats from my search (these have the type of L which is a single char in a struct) and only focus on Helicopters, represented by a H which is a single char in a struct.

The problem I have is that when I have this for loop:

closest_index = 0;

for (j = 0; j < asset_size; j++) {
        printf("type : %c \n", (assets + j)->type);
        if ((assets + j)->type == 'H') {
            if (((assets + j) ->distance_from_mayday) < ((assets + closest_index) ->distance_from_mayday)) {
                closest_index = j;
                printf("closest_index heli = %d \n", closest_index);

            }
        }
    }

It definitely gets called, I added the line:

 printf("type : %c \n", (assets + j)->type);

just before the comparison, and it produces this result in the console:

type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : L 
type : H 
type : H 
type : H 
type : H 
type : H 
type : H

As you can see there is values of H so I don't understand why this for loop is not executing as intented, any ideas?

Upvotes: 0

Views: 145

Answers (3)

Adam Liss
Adam Liss

Reputation: 48330

The problem isn't the for; it's the if: none of your helicopters is closer than the first lifeboat. Here's one way to fix this:

closest_index = -1;

for (j = 0; j < asset_size; j++) {
  printf("type : %c\n", (assets + j)->type);
  if ((assets + j)->type == 'H') {
    if ((closest_index < 0) ||
        (assets + j)->distance_from_mayday <
            (assets + closest_index)->distance_from_mayday) {
      closest_index = j;
      printf("closest_index heli = %d\n", closest_index);
    }
  }
}

As a bonus, the loop will exit with closest_index == -1 if there are no helicopters.

If you care about the closest asset but not the index, you can simplify the loop as well:

Asset *closest_asset = NULL;

for (j = 0; j < asset_size; j++) {
  Asset *this_asset = assets + j;
  printf("type : %c\n", this_asset->type);
  if (this_asset->type == 'H' &&
      (closest_asset == NULL ||
       this_asset->distance_from_mayday < closest_asset->distance_from_mayday) {
    closest_asset = this_asset;
    printf("closest_index heli = %d\n", j);
  }
}

Upvotes: 1

ensc
ensc

Reputation: 6994

I guess, first element in list is of type 'L' and is lower or equal than any 'H' value. Your closest_index marker won't be moved hence.

It would be better to record the distance itself or use an impossible start value (-1?) for closest_index

EDIT:

Suggested code:

struct asset *result = NULL;

for (j = 0; j < asset_size; j++) {
     if (assets[j].type != 'H')
         continue;
     if (!result || assets[j].distance < result->distance)
         result = &assets[j];
}

Upvotes: 3

Daniel
Daniel

Reputation: 2004

Your code begins by assuming the first index in the array, in this case a life boat, is the closest helicopter to the event.

Maybe try something like this:

closest_index = 0;
closest_distance = INT_MAX;

for (j = 0; j < asset_size; j++) {
        printf("type : %c \n", assets[j]->type);
        if (assets[j]->type == 'H') {
            if (assets[j]->distance_from_mayday < closest_distance)  {
                closest_index = j;
                closest_distance = assets[j]->distance_from_mayday;
                printf("closest_index heli = %d \n", closest_index);
            }
        }
    }

If your list will always be sorted with the helis at the end (and you will always have at least one heli) then you could fix by changing your initial condition to:

closest_index = asset_size -1;

Upvotes: 1

Related Questions