【问题标题】:function that can NULL a passed pointer可以使传递的指针为空的函数
【发布时间】:2012-07-15 23:22:16
【问题描述】:

现在有

void clistDeleteNode(clist_t *list,cnode_t **pnode) {
    cnode_t *node=*pnode;

    /* stuff done with node here, removed for clarity */

    free(*pnode);
    *pnode=0;
}

被调用的

clistDeleteNode(list,&aNode);

函数释放后自动将最终用户指针设为 NULL - 我这样做是因为它使调试和泄漏检查更容易。

有没有更优雅的方法来传递一个指向函数的指针,例如它可以被修改而不必使用 *&*aNode ? (从最终用户的角度)

【问题讨论】:

  • 并非没有滥用宏...
  • & 只是一个字符,它清楚地表明该值可以被修改,而不仅仅是使用。我不确定你如何改进它。
  • 这只是因为它与所有其他函数(在相关函数组中)不同 - 我不知道是否有某种方法可以将参数标记为“通过引用”例如在函数 decleration
  • github.com/chriscamacho/clist 将整个(简单)项目放在 github 上 - 有人可能会觉得它很有用,但老实说,这更适合智力挑战......

标签: c function pass-by-reference


【解决方案1】:

与 C++ 不同,没有在调用函数中使用 & 运算符的情况下,无法传递 aNode 的地址。

使用预处理器隐藏你实际在做的事情很可能被认为比上述清晰的方式更不“优雅”。

【讨论】:

    【解决方案2】:

    不,C 中没有 pass-by-reference 这样的东西,传递一个指向您想在另一个函数中更新的类型的指针是唯一且推荐的启用方式改变原来的变量。


    不推荐..真的,请不要使用它。

    我见过开发者(虽然自上次以来已经很久了)使用下面的东西只是为了让事情变得“更容易”,但老实说,我认为它比美观更让人头疼。

    #define REF(v) (&v)
    #define REF_TO(type, v) type *v
    #define DEREF(p) (*p)
    
    void
    func (REF_TO(int*, p))
    {
      DEREF(p) = 0;
    }
    
    int
    main (int argc, char* argv[])
    {
      int *p;
    
      func (REF(p));
    
      return 0;
    }
    

    不要 - 不要 - 使用 - 它,认真的。

    【讨论】:

    • 是的,那个代码太可怕了。我建议删除它,因为最好不要给任何人想法......
    • gggaaah 哦,我的眼睛 - 它更复杂而不是更优雅!
    • @ChrisCamacho 完全正确,坚持使用更优雅的 & 符号,&
    【解决方案3】:

    没有。

    如果你想让一个函数修改x,你需要将&x传递给函数,不管是什么类型。

    您可以将其隐藏在宏后面,但这最终可能会更加令人困惑。

    【讨论】:

      【解决方案4】:

      是的,但它很难看;您可以使用数组类型和数组指针衰减来模拟参考参数。

      typedef void (*void_ptr_ref)[1];
      void func(void_ptr_ref p) {
          p[0] = 0;
      }
      int main() {
          void_ptr_ref p;
          func(p);
          /* do stuff with p */
      }
      

      Posix 实际上为jmp_buf 类型(在setjmp.h 中使用)使用了这种(可怕的!)样式。

      只有当您的“指针”类型打算用作不透明类型时,这才是真正值得的;您当然不希望用户必须双重间接 void_ptr_ref p 或必须投射它等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-07
        • 2017-07-07
        • 2015-07-06
        • 2015-08-05
        • 1970-01-01
        • 1970-01-01
        • 2013-10-25
        相关资源
        最近更新 更多