1

Again I have a very stupid question, I just can't find an answer to. This time I want to know, why the member method works. Especially the while loop in the member method. So why does the following code work:

while(current){
  if(current->i==a){
  return 1;
  }
  ...
}

Why does the argument while(current) not produce a infinite execution?

This is the whole program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct liste{
  int i;
  struct liste *next;
};

struct liste *m [4];
struct liste *current;

int hash(int b){
  printf("%i\n",sizeof(m));
  return b%sizeof(m);
}

int insert(int a){
  struct liste *new = malloc(sizeof(struct liste));
  if(new){
    new->i = a;
    new->next=m[hash(a)];
    m[hash(a)] = new;
    return 1;
  }
  return 0;
}

int member(int a){
  current = m[hash(a)];
  while(current){
    if(current->i==a){
      return 1;
    }
    current = current->next;
  }
  return 0;
}
honk
  • 9,137
  • 11
  • 75
  • 83
Mettwurst
  • 33
  • 5
  • The 1st snippet won't even compile. – alk Jul 10 '15 at 19:20
  • You perhaps want to switch to a more sane indention scheme ...? – alk Jul 10 '15 at 19:21
  • 1
    OT: Appliying the `sizeof` operator evaluates to `size_t`, which is `unsigned`, so using the `i` conversion specifier is wrong in any case. In a POSIX environment us `zu`, under windows use `u` (32bit) or `lu` (64bit). – alk Jul 10 '15 at 19:25

2 Answers2

4

You have to consider the complete while loop:

while(current){
    if(current->i==a){
        return 1;
    }   
    current = current->next;
}

As long as the condition of the if is false, current is modified in each cycle of the while loop.

Also, in case a is not in the list, current will become NULL (or 0) after the whole list was searched. Then the while loop will terminate, because its condition is evaluated to false.

Note: In your program, the array m is a global variable. Global variables are always initialized to 0. The initial value of an array element is copied to the next pointer in the insert() function in the following line:

new->next=m[hash(a)];

Therefore, the final next in the list will always be 0.

Community
  • 1
  • 1
honk
  • 9,137
  • 11
  • 75
  • 83
  • But why does current become 'Null', the array m contains struct pointers. Those contain per default a random address. – Mettwurst Jul 10 '15 at 18:42
  • I can't see it from the code that you posted, but I assumed that the `next` pointer of a `list` element is initialized to `NULL`. – honk Jul 10 '15 at 18:46
  • No they aren't and that's the hook. Thats why I don't understand why this code works. – Mettwurst Jul 10 '15 at 18:49
  • IMHO, if the 4 elements of `m` are not set to `NULL` or 0, for example, in your `main()` function, then the code shouln't work reliably. This is, because the initial value of an array element is copied to the `next` pointer in the `insert()` function. – honk Jul 10 '15 at 19:13
  • That's correct. It shouldn't work, but it works. By the way, this is not my code, but the code of a friend of mine and I can't understand why this works even on my machine with an up to date gcc. – Mettwurst Jul 10 '15 at 19:30
  • 2
    Ah, now I got it. The array `m` is a global variable. [Global variables are always initialized to 0](http://stackoverflow.com/q/14049777/2675154). – honk Jul 10 '15 at 19:36
2

Your first code snippet doesn't cover all of the loop:

 while(current) {
   if(current->i==a) {
     return 1;
   }   
   current = current->next; // Important!
 } // this is the end of the loop's body

The last statement inside the loop changes the value of current. Eventually it'll be NULL, which is when the loop terminates.


Seems your question is more about why this

// ...
current = m[hash(a)];
while(current){
// ...

works even though the elements of m weren't explicitly initialised to NULL. As pointed out in the comments of the other answer the reason is that globals are - in contrast to local variables - default initialised.

I'd would like to add that IMHO the code in its current form isn't well written. Since this is effectively a hash table, this should be packed into functions operating on some struct hashtable instead of some global variables.

Daniel Jour
  • 15,896
  • 2
  • 36
  • 63