C函数中作为参数的指针

C函数中作为参数的指针,c,pointers,linked-list,C,Pointers,Linked List,在我读过的许多示例中,一个简单的getListLength()函数如下所示: int getListLength(struct node *head) { struct node *temp = head; int iCount = 0; while (temp) { ++iCount; temp = temp->next; } return iCount; } 我觉得不需要的是复制传递参数的本地指针(在

在我读过的许多示例中,一个简单的getListLength()函数如下所示:

int getListLength(struct node *head)
{
    struct node *temp = head;
    int iCount = 0;

    while (temp)
    {
        ++iCount;
        temp = temp->next;
    }

    return iCount;
}
我觉得不需要的是复制传递参数的本地指针(在本例中为*temp)的声明。如果我没有记错的话,传递的参数将获得它们自己的副本。因此,不会因为*头本身就是副本,就需要一个复制*头的本地指针,对吧?
换句话说,放弃*temp指针并在任何地方使用head是否正确?

是的,它是一个副本,所以是的,它是正确的

int getListLength(struct node* head)
{
    int iCount = 0;

    while (head)
    {
        ++iCount;
        head = head->next;
    }
    return iCount;
}

为什么不执行它并亲自查看呢?

虽然确实不需要本地副本,因为指针是按值传递的,但它可能是出于风格原因而存在的。有些人认为修改传入的参数是不好的(虽然在某些情况下我认为它是有用的),但是更重要的是,您丢失了代码中的一些自文档;具体来说,
head
不再总是指向链接列表的真正head。这在您的短小代码中并没有那么容易混淆,但是当代码较长且更复杂时,命名不准确的变量可能更容易混淆。

通常,制作传入指针的本地副本的原因是为了减少函数的复杂性(通过不修改函数参数)

如果一个函数只使用指针进行读取(而不是写入),并且与外部世界没有其他交互,那么该函数可以在GCC中被注释为“pure”,并且可以进行一些很好的优化

例如:

__attribute__((pure)) int getListLength(struct node *head) 
{
    struct node *temp = head;
    int iCount = 0;

    while (temp)
    {
        ++iCount;
        temp = temp->next;
    }

    return iCount;
}

如果您不熟悉副作用是什么,请尝试阅读和Wikipedia的文章,以获得有关该主题的更多信息。

“当代码更长、更复杂时。”-我可以反驳这一点。如果一个函数比发布的一个OP长,如果它太复杂,以至于需要执行多个任务,并且需要记住变量名,那么该函数可能应该重构。这可能是真的,但现实世界很少像人们希望的那样完美。