如果我需要不可变地传递对 int 的引用,我可以将其作为
const int*
传递给函数,而不是 int*
。这也有助于界面显示指向的数据不会被改变。
现在我有一个带有双向链表的双端队列,如何才能不可变地传递它?将其作为
const
传递不会执行任何操作,因为它只会确保指针的不变性,而不是指向的数据
最小示例:
#include <stdlib.h>
#include <stdio.h>
typedef struct Node Node;
struct Node {
int val;
Node* prev;
Node* next;
};
typedef struct {
Node* head;
Node* tail;
} Deque;
int deque_size(Deque dq) {
int sz = 0;
Node* current = dq.head;
while (current)
{
current = current->next;
sz++;
}
// surprise
if (dq.head)
dq.head->val = 42;
return sz;
}
int main(void) {
Deque dq;
dq.head = NULL;
dq.tail = NULL;
Node* node = malloc(sizeof(*node));
node->val = 1;
node->prev = NULL;
node->next = NULL;
dq.head = node;
dq.tail = node;
printf("first value: %d\n", dq.head->val);
printf("deque size: %d\n", deque_size(dq));
printf("first value: %d\n", dq.head->val);
}
观察到的输出:
first value: 1
deque size: 1
first value: 42
deque_size
偷偷地改变了数据结构。
预期行为:
编译器不允许我改变数据,或者至少我希望模块的 API 向用户保证我的小指承诺不会改变它。
您可以将 const 指针传递给 deque_size 函数。
int deque_size(const Deque* dq);
这样,函数就无法在编译期间不抛出错误的情况下改变结构或其值。
您甚至可以将指针本身声明为 const,这样就无法将其更改为指向不同的内存,如下所示:
int deque_size(const Deque* const dq);
请记住,这只是向函数调用者传达意图的一种方式。因为在 C 中,可以使用强制转换在函数内删除 const 关键字。您可以使用单元测试进行检查以确保没有发生突变。
另请参阅:
常量指针与指向常量的指针
https://stackoverflow.com/a/41744707/7312954