假设我有以下结构来定义列表节点:
struct node {
int data;
struct node* next;
};
我有这个函数来获取列表的长度:
int Length(struct node* head) {
struct node* current = head;
int count = 0;
while (current != NULL) {
count++;
current = current->next;
}
return count;
}
为什么我要这样做:struct node* current = head;
而不是只是在头上迭代?
那么,为什么这不对呢:
int Length(struct node* head) {
int count = 0;
while (head != NULL) {
count++;
head = head->next;
}
return count;
}
一旦进入长度函数,头部是否会失去范围,因此即使我们执行head = head-> next,它也不会在函数外部受到影响?
由于
答案 0 :(得分:4)
您的两个代码段是等效的。
但是,有一种思想流派认为你不应该修改函数参数,以避免潜在的编程错误,并增强可读性(你并没有真正修改头部)。为此,您经常会看到人们将尽可能多的参数定义为const
。
答案 1 :(得分:0)
无论如何,智能编译器都会这样做。有些人为了清晰起见这样做,因为他们的头部意味着列表的头部,而当前只是迭代器,这只是为了可读性。
答案 2 :(得分:0)
我所知道的程序员都直观地假设在整个函数中,通过值传递的参数值(例如指针引用的地址)保持不变。由于这个假设,在扩展函数时很容易引入一些小错误。想象一下,我想在您的Length
函数中打印一些调试信息:
int Length(struct node* head) {
int count = 0;
while (head != NULL) {
count++;
head = head->next;
}
printf( "Length of list at %p is %d\n", head, count );
return count;
}
函数越大(或者逻辑越多,或者修改的人越少关注......),这种问题就越容易发生。
对于简短的功能,例如Length
,我个人认为它很好(我也这样做)。