如何将头尾链表不变地传递给函数?

问题描述 投票:0回答:1

如果我需要不可变地传递对 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 向用户保证我的小指承诺不会改变它。

c pointers data-structures linked-list deque
1个回答
0
投票

您可以将 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

© www.soinside.com 2019 - 2024. All rights reserved.