【问题标题】:What is forward reference in C?什么是 C 中的前向引用?
【发布时间】:2010-09-24 11:34:13
【问题描述】:

C 中关于指针的前向引用是什么?

我可以举个例子吗?

【问题讨论】:

    标签: c pointers forward-reference


    【解决方案1】:

    forward references 上查看此页面。我看不出前向引用与指针和其他 PoD 类型有何不同。

    请注意,您可以转发声明类型,并声明指向该类型的变量:

    struct MyStruct;
    struct MyStruct *ptr;
    struct MyStruct var;  // ILLEGAL
    ptr->member;  // ILLEGAL
    
    struct MyStruct {
        // ...
    };
    
    // Or:
    
    typedef struct MyStruct MyStruct;
    MyStruct *ptr;
    MyStruct var;  // ILLEGAL
    ptr->member;  // ILLEGAL
    
    struct MyStruct {
        // ...
    };
    

    我认为这是您在处理指针和前向声明时所要求的。

    【讨论】:

    • 好的,谢谢你,但我可以假设在这种情况下指针没有区别
    • 是的:指针变量是变量,整数变量也是。
    【解决方案2】:

    我认为关于指针的“前向引用”是这样的:

    struct MyStruct *ptr; // this is a forward reference.
    
    struct MyStruct
    {
      struct MyStruct *next; // another forward reference - this is much more useful
      // some data members
    };
    

    在定义它指向的结构之前声明指针。

    编译器可以解决这个问题,因为指针存储了一个地址,您不需要知道该地址是什么来为指针保留内存。

    【讨论】:

      【解决方案3】:

      前向引用是当你声明一个类型但没有定义它时。

      它允许您通过指针(或 C++ 的引用)使用类型,但您不能声明变量。

      这是一种告诉编译器存在某种东西的方式

      假设您在 Plop.h 中定义了一个 Plop 结构:

      struct Plop
      {
         int n;
         float f;
      };
      

      现在您想添加一些适用于该结构的实用程序函数。您创建另一个文件 PlopUtils.h(假设您无法更改 Plop.h):

      struct Plop; // Instead of including Plop.h, just use a forward declaration to speed up compile time
      
      void doSomething(Plop* plop);
      void doNothing(Plop* plop);
      

      现在,当您实现这些功能时,您将需要结构定义,因此您需要在 PlopUtils.cpp 中包含 Plop.h 文件:

      #include "PlopUtils.h"
      #include "Plop.h" // now we need to include the header in order to work with the type
      
      void doSomething(Plop* plop)
      {
         plop->n ...
      }
      
      void doNothing(Plop* plop);
      {
         plop->f ...
      }
      

      【讨论】:

        【解决方案4】:

        我认为 C 编译器最初有一个过程,它可以同时进行符号表构建和语义分析。比如:

            ....
            ... foo(a,b) + 1 ... // assumes foo returns int
            ....
        
            double foo(double x, double y){ ... } // violates earlier assumption
        

        为了防止这种情况,你说:

            double foo(double x, double y); // this is the forward declaration
        
            ....
            ... foo(a,b) + 1 ... // correct assumptions made
            ....
        
            double foo(double x, double y){ ... } // this is the real declaration
        

        帕斯卡也有同样的概念。

        【讨论】:

          【解决方案5】:

          添加到以前的答案。强制前向引用的典型情况是 struct foo 包含指向 struct bar 的指针,而 bar 包含指向 foo 的指针(声明之间的循环依赖)。在 C 中表达这种情况的唯一方法是使用前向声明,即:

          struct foo;
          
          struct bar
          {
             struct foo *f;
          };
          
          struct foo
          {
             struct bar *b;
          };
          

          【讨论】:

            【解决方案6】:

            前向引用允许 C 编译器执行更少的传递并显着减少编译时间。大约 20 年前,当计算机速度慢得多且编译器效率较低时,这可能很重要。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-06-13
              • 2017-03-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-15
              • 1970-01-01
              • 2016-01-17
              相关资源
              最近更新 更多