C 中的 const 结构参数

const Struct parameter in C

我正在研究简单的二叉树。 我看到了一个模型答案并提出了一个问题。 在此代码中 ItemTree 是结构。

typedef struct {
    char characters[20];
    char name[20];
} Item;

typedef struct node {
    Item item;
    struct node* left;
    struct node* right;
} Node;

typedef struct tree {
    Node* root;
    int size;
} Tree;

我将展示两个函数原型。

bool InTree(const Item* pi, const Tree* ptree);
Item* TreeSearch(Tree* ptree, const Item key);

一个是使用Item*,另一个是通过参数使用Item。我知道每一个的意思。但是当使用const的时候,我觉得这两者没有区别。如果我们假设内存足够大。

const Item* piconst Item key 用作函数的参数时哪个更好? 是编码风格问题还是有意为之?

/* 1 */ void foo(Item *pi)
/* 2 */ void foo(const Item *pi)
/* 3 */ void foo(const Item * const pi)

这三个都将传递对结构的引用,而不是结构本身。区别是:

  1. 指针pi和引用的结构可以修改
  2. 指针pi可以修改,引用的结构体不能修改
  3. 指针pi和引用的结构无法修改
/* 1 */ void foo(Item pi)
/* 2 */ void foo(const Item pi)

在这两种情况下,结构将按值复制,即整个结构将传递给函数。修改成员不会影响原来的结构。

  1. struct pi可以修改
  2. 结构pi无法修改

在这两种使用说明符声明参数的方法之间Item

bool InTree(const Item* pi, const Tree* ptree);
Item* TreeSearch(Tree* ptree, const Item key);

与声明 const Item key 相比,声明参数 const Item* pi 的方法更可取,因为在第二种情况下,包含字符数组的结构类型的整个对象被复制而不是复制只有一个指向更有效的对象的指针。

const Item *pi表示*pi*(pi + index)(或pi[index])不能修改。

const Item key 表示 key 不能被修改(在变量的情况下初始化之后,或者在函数参数的情况下作为函数调用的一部分赋值之后)。


bool InTree(const Item* pi, const Tree* ptree);

我猜InTree搜索pi指向的特定Item节点是否存在于ptree指向的根节点的树中。 (即它正在搜索指向特定 Item 的指针,而不是搜索匹配的 Item。)无需修改树中的任何 ItemItempi 指向,因此两个参数都可以是 const Item * 类型,以指示函数不会修改任何内容。


Item* TreeSearch(Tree* ptree, const Item key);

我猜想TreeSearch搜索根节点被ptree指向的树来找到匹配Item key的节点。我猜想只有 Item 的“值”部分将与树中的节点进行比较,而 Item 的“链接”部分将被忽略。我猜函数将 return 一个指向树中匹配节点中 Item 的指针,如果找到的话,它将 return 一个空指针。

将参数 key 声明为 const Item key 是编码风格问题。它对函数的调用者没有影响,因为参数是按值传递的。只是在函数定义上有所不同,防止函数体修改参数的值。

我想参数 ptree 可以声明为 const Tree * 假设函数不修改 *ptree.

我猜函数 return 类型是 Item * 而不是 const Item * 因为函数的调用者可能想要修改(间接) returned Item 在某种程度上。


作为旁注,即使 TreeSearch 函数定义为

Item* TreeSearch(Tree* ptree, const Item key)
{
    /* ... implementation omitted ... */
}

那么它将匹配这个没有 const 限定符的声明

Item* TreeSearch(Tree* ptree, Item key);

因此参数 keyconst 限定符在函数的 声明 中确实是多余的,即使它在 函数的定义

这不适用于 InTree 函数的声明。


对于Item* TreeSearch(Tree* ptree, const Item key);,如果类型Item被认为是“大”,那么将参数key更改为const Item *key会更实用,以便减少函数调用开销。程序员应该对此做出最好的判断。然后将定义该函数以在树中找到 匹配 *keyItem 节点(仅考虑 ItemItem 的“值”部分忽略“链接”部分),而不是找到 key.

指向的 specific Item 节点