在C中,如何通过列表改进迭代?

时间:2015-04-27 10:39:03

标签: c

我有自己的模拟堆块的数据结构。

typedef struct heap_block
{
   struct heap_block* next;
   size_t size;
   bool isfree;
} header;

我有一个迭代我的数据结构的方法(它就像一个列表):

void craw(header* crawler, bool isfree, int* counter)
 {
   while(crawler->next != NULL)
   {
     if(crawler->isfree == isfree)
     {
         ++(*counter);
     }

     crawler = crawler->next;
   }

   if(crawler->isfree == isfree)
   {
      ++(*counter);
   }
}

我需要使用额外的检查,因为最后一个元素有crawler->next == NULL

如何改进此迭代?

4 个答案:

答案 0 :(得分:2)

您可能希望将循环测试更改为while (crawler != NULL) { ... },如下所示:

void craw(header* crawler, bool isfree, int* counter)
 {
   while(crawler != NULL)
   {
     if(crawler->isfree == isfree)
     {
         ++(*counter);
     }

     crawler = crawler->next;
   }
}

此更改还可以防止在使用craw()抓取工具调用NULL时代码崩溃。

答案 1 :(得分:2)

这可能是您可以迭代链表的最简洁方法。

void craw(header* crawler, bool isfree, int* counter)
{
    for (; crawler; crawler = crawler->next)
    {
         if (crawler->isFree == isFree)
             ++(*counter); 
    }
}

答案 2 :(得分:2)

我正在寻找性能改进,但如果没有实际分析发布版本中的代码,很难说。优化器可以做你从未梦想过的事情。也就是说,你可以做的一件事就是在每次迭代时都不要取消引用计数器。没有任何内容表明它的内存将与其余的derefrenced列表数据一起被分页,因此在每次迭代时取消引用它可能会带来昂贵的提取。相反,在迭代开始之前分配一个本地计数器,在每次迭代时增加它,并在返回之前分配解除引用的计数器参数。

void craw(header* crawler, bool isfree, int* counter)
{
    int local_counter = *counter; // assuming counter != 0

    ... iterate ...
    local_counter++;

    *counter = local_counter;    
}

答案 3 :(得分:2)

如果结果可以通过返回值返回,则无需按引用进行调用。因此,您可以将函数更改为 true 函数,而不是void " procedure"

unsigned crawl2(header *crawler, bool isfree)
{
unsigned count;

    for (count =0; crawler; crawler=crawler->next)
    {
         if (crawler->isFree != isFree) continue;
         count++; 
    }
return count;
}

注意:如果内联函数,事情可能会有所不同。在这种情况下,*计数器的引用可以解析为直接的(并且它甚至可以在循环期间保存在寄存器中)