3

I have an array of int that is terminated with a '\0' created elsewhere in my code. I know it's null terminated because I've tested it.

Say, for this example, the array is [7, 8, 9, 11, 12, '\0']

When I feed it to my function:

int edgesInCluster(Graph *g, int *nodes) {
    int count = 0;
    int i = 0;
    int j = 0;
    while(nodes[i] != '\0') {
        while(nodes[j] != '\0') {
            if(i<j) {
                printf("%i %i\n", nodes[i], nodes[j]);
                count += isNeighbour(g, nodes[i], nodes[j]);
            }
            j++;
        }
        i++;
    }
    return count;
}

The printf is outputting:

7 7
7 8
7 9
7 11
7 12

When it should be outputting:

7 8
7 9
7 11
7 12
8 9
8 11
8 12
9 11
9 12
11 12

Which means that for some reason either 'i' isn't being incremented (but we can see that it is) or nodes[0] == '\0' which we know isn't true since the loop with 'j' works fine.

So, any ideas what's going on?

P.S. when I change the whiles to for loops, it works but only if I know the length of 'nodes'

2 Answers 2

4

You don't reset your j after the inner loop.

But why such a horribly verbose code? Try this:

size_t count = 0;

for (size_t i = 0; nodes[i]; ++i)
{
  for (size_t j = i + 1;  nodes[j]; ++j)
  {
    printf("%i %i\n", nodes[i], nodes[j]);
    count += isNeighbour(g, nodes[i], nodes[j]);
  }
}

return count;

(If you want strict ANSI C89, you have to pull the declarations of i and j out of the loops of course.)

Also note that '\0' is a char-literal of value 0, so you might just as well, and more correctly, say 0. And instead of if (x != 0) you can just say if (x), which is what I did in the for loops.

Sign up to request clarification or add additional context in comments.

6 Comments

Ah, silly me! I write verbose until I know it all works then I can reduce it if necessary. For what it's worth I compile as c99 with -Wall and -pedantic and I get no warnings - seems more important than less verbosity. Thanks for your help.
@Griffin: But your verbosity was actually obscuring the logic. The for-loops are ideal for expressing the semantics of a ranged loop, so by "doing it manually" all you did was confuse yourself... Also note that my loop is more efficient by starting at the correct value and not having to do the if (i < j) check every time.
Point taken, thanks. Just out of interest, why size_t instead of int?
@Griffin: The natural data type for array indices and counts is size_t. It's the return type of the sizeof operator, and usually typedef'd to unsigned int. Since your values are unsigned integers, best to use the most appropriate data type.
@Kerrek SB (sorry didn't realise that was the etiquette). Noted about the unsigned ints, thank you again.
|
1

You aren't resetting the value for j at the beginning of the j loop. That way, after the first loop, nodes[j] is '\0' for all following loops, aborting the j loop immediately.

2 Comments

Cheers, Kerrek SB just pipped you to the post!
yeah, his proposal is better anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.