【问题标题】:Pointers as arguments in C functions指针作为 C 函数中的参数
【发布时间】:2013-01-05 20:45:17
【问题描述】:

在我读过的很多例子中,一个简单的 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 是否正确?

【问题讨论】:

    标签: c pointers linked-list


    【解决方案1】:

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

    int getListLength(struct node* head)
    {
        int iCount = 0;
    
        while (head)
        {
            ++iCount;
            head = head->next;
        }
        return iCount;
    }
    

    你为什么不执行它自己看看?

    【讨论】:

      【解决方案2】:

      虽然确实不需要本地副本,因为指针是按值传递的,但可能出于文体原因。有些人认为修改传入的参数是不好的形式(尽管我确实发现它在某些情况下很有用),但也许更重要的是,您会丢失代码中的一些自我文档;具体来说,head 不再总是指向链表的真正头部。这在您的一小段代码中并没有那么令人困惑,但是当代码更长且更复杂时,具有不准确命名的变量可能会更加令人困惑。

      【讨论】:

      • "当代码更长更复杂时。" - 我可以反驳这一点。如果一个函数比发布的一个 OP 更长,并且如果它太复杂以至于它执行多个任务并且需要记住变量名称,那么该函数可能应该被重构。
      • 这可能是真的,但现实世界很少像人们想象的那样完美。
      【解决方案3】:

      通常,制作传入指针的本地副本的原因是减少函数的side-effects(通过不修改函数参数)。

      如果一个函数只使用指针读取(不写入),并且与外界没有其他交互,则该函数可以注释为'pure' 在 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 维基百科文章以获取有关该主题的更多信息。

      【讨论】:

        猜你喜欢
        • 2013-09-12
        • 1970-01-01
        • 2017-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多