I'm studying simple binary tree. I saw a model answer and had a question. In this code Item
and Tree
are structs.
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;
And I'll show two function prototypes.
bool InTree(const Item* pi, const Tree* ptree);
Item* TreeSearch(Tree* ptree, const Item key);
One is using Item* and the other is using Item by parameter. I know what each means. But when const
is used, I think there is no difference between these two. If we assumed the memory is big enough.
const Item* pi
and const Item key
which is better when used as a parameter for a function? Is it about coding style problem or is it intended?
/* 1 */ void foo(Item *pi)
/* 2 */ void foo(const Item *pi)
/* 3 */ void foo(const Item * const pi)
All three will pass the reference to the struct, not the struct itself. The difference is:
pi
and the referenced struct can be modifiedpi
can be modified, the referenced struct cannot be modifiedpi
and the referenced struct cannot be modified/* 1 */ void foo(Item pi)
/* 2 */ void foo(const Item pi)
In both cases struct will be copied by value ie the whole struct will be passed to the function. If you modify the member it will not affect the original struct.
pi
can be modifiedpi
cannot be modifiedBetween these two approaches of declarations of parameters with the specifier Item
bool InTree(const Item* pi, const Tree* ptree);
Item* TreeSearch(Tree* ptree, const Item key);
the approach with declaration the parameter like const Item* pi
is more preferable compared with the declaration const Item key
because in the second case the whole object of the structure type that contains character arrays is copied instead of coping only a pointer to the object that is more efficient.
const Item *pi
means that *pi
or *(pi + index)
(or pi[index]
) cannot be modified.
const Item key
means that key
cannot be modified (after initialization in the case of a variable, or after assignment as part of the function call in the case of a function parameter).
bool InTree(const Item* pi, const Tree* ptree);
I guess that InTree
searches whether the specific Item
node pointed to by pi
is present in the tree whose root node is pointed to by ptree
. (Ie it is searching for a pointer to the specific Item
rather than searching for a matching Item
.) There is no need to modify any Item
in the tree or the Item
pointed to by pi
, so both parameters can be of type const Item *
to indicate that nothing will be modified by the function.
Item* TreeSearch(Tree* ptree, const Item key);
I guess that TreeSearch
searches the tree whose root node is pointed to by ptree
to find a node that matches Item key
. I guess that only the "value" parts of the Item
will be compared with nodes in the tree and the "linkage" parts of the Item
will be ignored. I guess the function will return a pointer to the Item
in the matching node in the tree if one is found, otherwise it will return a null pointer.
Declaring the parameter key
as const Item key
is a coding style issue. It makes no difference to the caller of the function because arguments are passed by value. It only makes a difference in the function definition, preventing the function body from modifying the value of the parameter.
I guess the parameter ptree
could be declared as const Tree *
assuming the function does not modify the *ptree
.
I guess the function return type is Item *
rather than const Item *
because the caller of the function might want to modify the (indirectly) returned Item
in some way.
As a side note, even if the TreeSearch
function is defined as
Item* TreeSearch(Tree* ptree, const Item key)
{
/* ... implementation omitted ... */
}
then it will match this declaration without the const
qualifier
Item* TreeSearch(Tree* ptree, Item key);
so that const
qualifier for parameter key
really is superfluous in the declaration of the function, even if it is not superfluous in the definition of the function.
That does not apply to the declaration of the InTree
function.
For Item* TreeSearch(Tree* ptree, const Item key);
, if the type Item
is considered "large", then it would be more practical to change the parameter key
to const Item *key
in order to reduce the function call overhead. The programmer should use their best judgement about that. The function would then be defined to find an Item
node in the tree that matches *key
(considering only the "value" parts of Item
and ignoring the "linkage" parts), not to find the specific Item
node pointed to by key
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.