C奇怪的指针算术2

时间:2015-07-10 18:21:53

标签: c pointers struct

我再次提出一个非常愚蠢的问题,我无法找到答案。这次我想知道,为什么成员方法有效。特别是成员方法中的while循环。那么为什么以下代码有效:

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

为什么参数while(current)不能产生无限执行?

这是整个计划:

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

2 个答案:

答案 0 :(得分:4)

您必须考虑完整的while循环:

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

只要if的条件为false,current循环的每个循环都会修改while

此外,如果a不在列表中,current将在搜索完整个列表后变为NULL(或0)。然后while循环将终止,因为它的条件被评估为false

注意:在您的程序中,数组m是一个全局变量。 Global variables are always initialized to 0。数组元素的初始值将复制到以下行中next函数中的insert()指针:

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

因此,列表中的最终next将始终为0.

答案 1 :(得分:2)

您的第一个代码段并未涵盖所有循环:

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

循环中的最后一个语句会更改current的值。最终它将是NULL,这是循环终止的时候。

似乎你的问题更多的是为什么这个

// ...
current = m[hash(a)];
while(current){
// ...
即使m的元素没有显式初始化为NULL,

仍然有效。正如在另一个答案的评论中指出的那样,原因是全局变量 - 与局部变量相反 - 默认初始化。

我想补充一点,恕我直言,目前形式的代码写得不好。由于这实际上是一个哈希表,因此应将其打包到在某些struct hashtable上运行的函数中,而不是某些全局变量。