指针作为C函数中的参数

时间:2013-01-05 20:45:17

标签: 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;
}

我不必要的是声明一个复制传递参数的本地指针(在本例中为* temp)。如果我没记错,传递的参数会获得自己的副本。因此,不需要复制* head的本地指针只是因为* head本身就是一个副本,对吗? 换句话说,丢弃* temp指针并在任何地方使用head是否正确?

3 个答案:

答案 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 EffectsFunctional Programming维基百科文章,以获取有关该主题的更多信息。