在很多例子中我读过一个简单的getListLength()函数看起来像这样:
int getListLength(struct node *head)
{
struct node *temp = head;
int iCount = 0;
while (temp)
{
++iCount;
temp = temp->next;
}
return iCount;
}
我不必要的是声明一个复制传递参数的本地指针(在本例中为* temp)。如果我没记错,传递的参数会获得自己的副本。因此,不需要复制* head的本地指针只是因为* head本身就是一个副本,对吗? 换句话说,丢弃* temp指针并在任何地方使用head是否正确?
答案 0 :(得分:4)
是的,这是副本,所以是的,这是正确的。
int getListLength(struct node* head)
{
int iCount = 0;
while (head)
{
++iCount;
head = head->next;
}
return iCount;
}
为什么不执行它并自己查看?
答案 1 :(得分:4)
虽然你确实不需要本地副本,因为指针是按值传递的,但它可能是出于文体原因。有人认为修改传入的参数是不好的形式(尽管我发现它在某些情况下很有用),但也许更重要的是,你丢失了代码中的一些自我文档;具体而言,head
不再总是指向链表的真正头部。这在您的短代码中并不令人困惑,但是当代码更长且更复杂时,如果命名不准确的变量会更加混乱。
答案 2 :(得分:2)
通常,制作传入指针的本地副本的原因是减少函数的side-effects(不修改函数参数)。
如果函数仅使用指针读取(不写入),并且没有与外界的其他交互,则该函数可以注释为 GCC中的“纯粹”,并且可以进行一些很好的优化。
示例:
__attribute__((pure)) int getListLength(struct node *head)
{
struct node *temp = head;
int iCount = 0;
while (temp)
{
++iCount;
temp = temp->next;
}
return iCount;
}
如果您不熟悉哪些副作用,请尝试阅读Side Effects和Functional Programming维基百科文章,以获取有关该主题的更多信息。