【问题标题】:Meaning of *& and **& in C++C++ 中 *& 和 **& 的含义
【发布时间】:2011-08-12 23:40:18
【问题描述】:

我在函数声明中多次找到这些符号,但我不知道它们的含义。

示例:

void raccogli_dati(double **& V, double **p, int N) { 
  int ultimo = 3; 
  V = new double * [N/2]; 
  for(int i=0; i < N/2; i++) { 
    V[i] = new double[N/2], std :: clog << "digita " << N/2 - i
                 << " valori per la parte superiore della matrice V: "; 
    for(int j=i; j < N/2; j++) 
      std :: cin >> V[i][j], p[ultimo++][0] = (V[i][j] /= sqrt(p[i][0]*p[j][0]));
  } 
  for(int i=1; i < N/2; i++) 
    for(int j=0; j < i; j++) 
       V[i][j] = V[j][i];
}

【问题讨论】:

  • 实际代码还是书本?对我来说,它看起来就像一个通用函数的符号。一个返回单个指针,另一个返回指向指针的指针。
  • 那些是对指针的引用。
  • This 网站可能对您有所帮助。 )

标签: c++ pointers syntax reference symbols


【解决方案1】:

这个 *& 在理论上和实际上都是可能的,并且被称为对指针变量的引用。它的行为就像一样。 此 *& 组合用作“传递”类型定义的函数参数。不像**也可以用于声明双指针变量。
参数的传递分为值传递、引用传递、指针传递。 关于可用的“通过”类型有各种答案。但是,我们需要了解此主题的基本知识。

按引用传递 --> 通常在传递给函数时对已创建的变量引用进行操作,例如 fun(int &amp;a);

按指针传递 --> 对传递给函数的已初始化的“指针变量/变量地址”进行操作,例如 fun(int* a);

auto addControl = [](SomeLabel** label, SomeControl** control) {
    *label = new SomeLabel;
    *control = new SomeControl;
    // few more operation further.
};

addControl(&m_label1,&m_control1);
addControl(&m_label2,&m_control2);
addControl(&m_label3,&m_control3);

在上面的例子中(这是我遇到的现实生活中的问题)我试图从 lambda 函数中初始化几个指针变量,为此我们需要通过双指针传递它,所以它带有 d-reference在该 lambda + 内部使用指针,同时在采用双指针的函数中传递指针时,您需要传递对指针变量的引用。

所以对于指针变量的引用,*& 这种组合会有所帮助。下面给出了我上面提到的同一个例子。

auto addControl = [](SomeLabel*& label, SomeControl*& control) {
        label = new SomeLabel;
        control = new SomeControl;
        // few more operation further.
    };

addControl(m_label1,m_control1);
addControl(m_label2,m_control2);
addControl(m_label3,m_control3);

所以在这里你可以看到你既不需要 d 引用,也不需要在传递函数时传递对指针变量的引用,因为当前按类型传递已经是对指针的引用。

希望这会有所帮助:-)

【讨论】:

    【解决方案2】:

    通常,您可以从右到左阅读变量的声明。因此,在 int *ptr; 的情况下,这意味着您有一个 Pointer * 指向一个 整数变量 int。此外,当它被声明为int **ptr2; 时,它是一个指针变量 * 指向一个指针变量 * 指向一个整数变量 @ 987654327@,与"(int *)* ptr2;"相同

    现在,按照声明 int*&amp; rPtr; 的语法,我们说它是一个 Reference &amp; 到一个 Pointer * 指向一个变量 类型为int。最后,您可以再次将这种方法应用于 int**&amp; rPtr2; 得出结论,它表示 Reference &amp;Pointer *Pointer em> *整数 int

    【讨论】:

    • +1 提示从右到左阅读声明:这大大加快了理解速度,也解释了为什么有时很难解释 C++ 构造(对于那些通常从左到右阅读的人)至少)
    【解决方案3】:

    int* 是指向int 的指针,因此int*&amp; 必须是对指向int 的指针的引用。同样,int** 是指向 int 的指针的指针,因此 int**&amp; 必须是指向 int 的指针的引用。

    【讨论】:

    • 我理解它们的字面意思,你能写一个例子来更有效地说明它们吗?
    【解决方案4】:

    *&amp; 表示通过引用接收指针。这意味着它是传递参数的别名。所以,它会影响传递参数。

    #include <iostream>
    using namespace std;
    
    void foo(int *ptr)
    {
        ptr = new int(50);    // Modifying the pointer to point to a different location
        cout << "In foo:\t" << *ptr << "\n"; 
        delete ptr ;
    }
    
    void bar(int *& ptr)
    {
        ptr = new int(80);    // Modifying the pointer to point to a different location
        cout << "In bar:\t" << *ptr << "\n"; 
        // Deleting the pointer will result the actual passed parameter dangling
    }
    int main()
    {
        int temp = 100 ;
        int *p = &temp ;
    
        cout << "Before foo:\t" << *p << "\n";
        foo(p) ;
        cout << "After foo:\t" << *p << "\n";
    
        cout << "Before bar:\t" << *p << "\n";
        bar(p) ;
        cout << "After bar:\t" << *p << "\n";
    
        delete p;
    
        return 0;
    }
    

    输出:

    Before foo: 100
    In foo: 50
    After foo:  100
    Before bar: 100
    In bar: 80
    After bar:  80
    

    【讨论】:

      【解决方案5】:

      要理解这些短语,让我们看看以下几件事:

      typedef double Foo;
      void fooFunc(Foo &_bar){ ... }
      

      所以这是通过引用传递一个双精度。

      typedef double* Foo;
      void fooFunc(Foo &_bar){ ... }
      

      现在它通过引用传递一个指向 double 的指针。

      typedef double** Foo;
      void fooFunc(Foo &_bar){ ... }
      

      最后,它通过引用传递一个指向 double 的指针。如果您按照这样的 typedef 进行思考,您将理解 & 和 * 的正确顺序以及它的含义。

      【讨论】:

        【解决方案6】:

        首先是对指针的引用,其次是对指针的引用。另请参阅how pointers and references differ 上的常见问题解答。

        void foo(int*& x, int**& y) {
            // modifying x or y here will modify a or b in main
        }
        
        int main() {
            int val = 42;
            int *a  = &val;
            int **b = &a;
        
            foo(a, b);
            return 0;
        }
        

        【讨论】:

        • 我知道我真的不应该,但我赞成这个答案只是因为它包含一个指针-指针-到-引用-到-典故-到-生命的意义。不知何故,我认为我们距离深度思考还有几年的时间。
        【解决方案7】:

        这是通过引用而不是值传递指针。例如,这允许更改函数中的指针(而不是指向的对象),以便调用代码看到更改。

        比较:

        void nochange( int* pointer ) //passed by value
        {
           pointer++; // change will be discarded once function returns
        }
        
        void change( int*& pointer ) //passed by reference
        {
           pointer++; // change will persist when function returns
        }
        

        【讨论】:

          【解决方案8】:

          这是通过引用获取参数。因此,在第一种情况下,您通过引用获取指针参数,因此您对指针值所做的任何修改都会反映在函数之外。第二个与第一个相似,唯一的区别是它是一个双指针。看这个例子:

          void pass_by_value(int* p)
          {
              //Allocate memory for int and store the address in p
              p = new int;
          }
          
          void pass_by_reference(int*& p)
          {
              p = new int;
          }
          
          int main()
          {
              int* p1 = NULL;
              int* p2 = NULL;
          
              pass_by_value(p1); //p1 will still be NULL after this call
              pass_by_reference(p2); //p2 's value is changed to point to the newly allocate memory
          
              return 0;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-01-23
            • 2011-05-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-03-26
            • 1970-01-01
            相关资源
            最近更新 更多