0

我读了一本书,其中给出了 .h 文件的示例,它相当于 java 中的队列接口:

void InitQueue(Queue* pQueue, int iSize);
bool Insert(Queue* pQueue, const Item* pItem);
bool Extract(Queue* pQueue, Item** pItem);
bool GetFirst(const Queue* pQueue, Item** pItem);
bool IsFull(const Queue* pQueue);
bool IsEmpty(const Queue* pQueue);

我不明白两件事:

  1. 为什么在Extract, GetFirst第二个参数是类型Item**而不是Item*?当我们写这样的事情时是什么意思?
  2. 为什么在某些函数 ( IsFull, IsEmpty, ..) 我们得到参数const Queue*而不是简单的Queue*
4

3 回答 3

3

IsFull() 和 IsEmpty() 采用 const 参数,因为这意味着它们不会更改 Queue 对象;它是恒定的,不会被修改。

Extract 和 GetFirst 使用 ** 是因为:

int a;           // Declares an int
a = 2;           // Sets a to 2
int *b = &a;     // Declares a pointer pointing to that int
*b = 4;          // Sets a to 4
int **c = &b;    // Declares a pointer pointing to that pointer to that int
**c = 6;         // Sets a to 6

如果我要将 c 传递给函数:

int global_var;

int main() {
  modify_ptr(c);
}

void modify_ptr(int **ptr)
{
  *ptr = &global_var;
}

我刚刚传入的指针本身就被修改了;**c 现在指向 global_var 而不是 a。

将这些指针传递给 getfirst 和 extract 的原因是因为它们是“getter”函数——您希望它们返回指向数据的指针。所以他们需要能够返回一个指针,并且他们采用的方法是将一个指针传递给一个指针,就像上面的例子一样,所以他们可以修改你传递给他们的内容以指向正确的元素。

于 2012-05-03T15:26:43.480 回答
2

为什么在ExtractGetFirst第二个参数是类型Item**而不是Item*?我们写这样的东西是什么意思?

这样就可以在函数内部更改指针。
最有可能的是,这意味着Item指针将由调用者传递,但将在函数内部分配。您不能只通过值传递指针来做到这一点,因为这会将内存分配给指针的副本,而不是传递的原始指针。

很难说程序员为什么使用调用者传递指针和分配它的函数的这种语义。理想情况下,人们会期望一种源-接收器机制。

为什么在某些函数(IsFull, IsEmpty, ..)中我们得到参数const Queue*而不是简单的Queue*

为了const 正确性
它向函数的用户表明指向的数据在函数内部不会改变。

于 2012-05-03T15:21:36.783 回答
1

为什么在 Extract 中,GetFirst 第二个参数的类型是 Item** 而不是 Item*?当我们写这样的事情时是什么意思?

这些是输出。队列显然包含一堆指向项目的指针。因为它是一个指针,所以我会只使用一个参数ExtractGetFirst返回一个指针。空指针将指示失败。开发人员没有这样做。相反,他们使用了旧的 C 风格的范例。为什么?谁知道。这不是写这些的最好方法。

为什么在某些函数(IsFull、IsEmpty、..)中我们得到参数 const Queue* 而不仅仅是 Queue*?

将参数标记为const告诉代码的用户该函数不会对参数的内容做任何事情。将此类未受干扰的引用和指针参数标记为const良好的编程习惯。

于 2012-05-03T15:25:16.817 回答