0

我对 c 和指针很陌生。每次我认为 k 我已经理解它时,都会出现一个我不太理解的问题(我花了一些时间阅读 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;
  } 
}

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

4

2 回答 2

3

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

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答案,谁建议更好的队列实现)

于 2013-02-03T16:14:24.940 回答
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]为更健壮的 。
于 2013-02-03T16:28:43.210 回答