Mettwurst
Mettwurst

Reputation: 33

C's weird pointer arithmetics 2

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;
}

Upvotes: 1

Views: 133

Answers (2)

Daniel Jour
Daniel Jour

Reputation: 16156

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.

Upvotes: 2

honk
honk

Reputation: 9743

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.

Upvotes: 4

Related Questions