【问题标题】:Using pointers for queue type使用队列类型的指针
【发布时间】:2013-02-03 16:07:19
【问题描述】:

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

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

【问题讨论】:

  • 有什么问题?你有错误吗?什么不工作?请准确,这样可以节省我们猜测的时间:)
  • @m0skit0:让我为你强调一下:有人能解释一下enqueue函数中指针的使用吗?
  • @AlokSave 解释什么?指针如何工作?我不明白他到底想知道什么……
  • @m0skit0 代码确实可以工作(用于遍历图形),但我不明白将指针作为变量而不是简单变量传递的好处是什么(enqueue(queue q , int x)) ?
  • 1) 你不需要last 元素,只需要first+count。 2) 对大小、计数和索引使用无符号类型是可取的(您不想要负索引或大小)

标签: c pointers queue


【解决方案1】:

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

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

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

按值传递队列

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

意思是

  • 作为参数给出的大量数据(将队列 myqueue 复制到 q 参数)
  • q被修改时,在enqueue函数内对q进行修改。 最初提供的队列(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 答案,谁建议更好的 queue 实现)

【讨论】:

    【解决方案2】:
    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]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-21
      • 2016-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多