1

假设我有以下结构来定义列表节点:

 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 进入 Length 函数后是否会失去作用域,因此即使我们执行 head = head->next 它也不会在函数之外受到影响?

谢谢

4

3 回答 3

4

您的两个代码片段是等效的。

然而,有一种观点认为你永远不应该修改函数参数,以避免潜在的编程错误,并提高可读性(你并没有真正修改头部)。为此,您经常会看到人们定义尽可能多的参数const

于 2013-01-16T22:13:27.027 回答
0

无论如何,智能编译器都会这样做。有些人这样做是为了清楚起见,因为 head 对他们来说意味着列表的头部,而 current 只是迭代器,它只是为了可读性。

于 2013-01-16T22:14:10.937 回答
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,我个人认为它很好(我也这样做)。

于 2013-01-16T22:41:14.760 回答