使用指针进行队列类型

时间:2013-02-03 16:07:20

标签: c pointers queue

我对c和指针很新。每当我瘦下来我都理解它时,会出现一个我不太懂的问题(我花了一些时间阅读c文档,但指针仍然不清楚):

typedef struct {
        int q[QUEUESIZE+1];
        int first;
        int last;
        int count;
} queue;

enqueue(queue *q, int x)
{
  if (q->count >= QUEUESIZE)
        printf("Warning: queue overflow enqueue x=%d\n",x);

  else {
    q->last = (q->last+1) % QUEUESIZE;
    q->q[ q->last ] = x;
    q->count = q->count + 1;
  } 
}

我希望我的问题不会太不透明,但有人可以解释在排队函数中使用指针吗?我认为排队的原则是分配一些精确的连续内存地址,但这肯定不是......

2 个答案:

答案 0 :(得分:3)

enqueue接受一个队列队列( queue 类型的队列)并在其中添加一个元素(由一个整数组成。

queue *q是一个指针,因为可能是

  • 可能有多个队列,参数告诉我们正在谈论的队列
  • 为了避免全局变量,队列作为参数给出 - 我们想要对队列的引用以便可以修改它,并且即使退出enqueue
  • ,修改也将保持生效

按值传递队列,如

enqueue(queue q, int x) { ...

意味着

  • 作为参数给出的大量数据(队列myqueue到q参数的副本)
  • 修改q时,会在q函数内的enqueue上进行修改。 最初提供的队列(myqueue)作为参数不会被修改

例如

enqueue(queue q, int x) { 
  q.count++; // only the local q.count is changed, not myqueue.count
  // ...
}

// ...

queue myqueue;
// ...
enqueue (myqueue, 3); // enqueue changes its local parameter, myqueue is not affected

此外,可以优化enqueue函数实现...(请参阅下面的 wildplasser 答案,建议更好的队列实现)

答案 1 :(得分:1)

struct queue {
        unsigned first;
        unsigned count;
        int q[QUEUESIZE];
        };

int enqueue(struct queue *q, int x)
{
  if (q->count >= QUEUESIZE) {
        fprintf(stderr, "Warning: queue overflow enqueue x=%d\n", x);
        return -1;
        }

  q->q[ (q->first+q->count++) % QUEUESIZE ] = x;
  return 0; /* success */ 
}

几点:

  • 诊断输出应该转到stderr
  • 使用无符号类型进行计数和偏移将(在大多数情况下)避免数字下溢(或将其转换为溢出,这将更快失败; - )
  • 你不需要三个元素{head,tail,count},只有两个{head,count}就足够了
  • 更少的变量:=更少的分配:=更少的线=更少的错误机会。
  • 范围检查和模数除法中的QUEUESIZE可能应该被sizeof q->q / sizeof q->q[0]取代,后者更强大。