【问题标题】:What's the difference between using * and using & in C++ functions?在 C++ 函数中使用 * 和使用 & 有什么区别?
【发布时间】:2015-05-08 09:53:58
【问题描述】:

我正在尝试使用以下代码对数组进行升序排序。我发现方法 1,2,3,4 都得到相同的结果:1234。

哪种方法最好?

我应该何时以及为什么应该使用指针/引用?谢谢你。

  1. 使用&调用,函数参数中使用*

  2. 只是在函数参数中使用了*

  1. 只是在函数参数中使用了&

  2. 什么都没有:

    #include <iostream>
    using namespace std;
    
    
    void swap(int a,int b){
    
        int t;
        t=a;
        a=b;
        b=t;
    }
    void main(){
    
        int a[]={1,2,3,4};
        for (int i=1; i<3; i++)
            for (int j=3; j>i;j--)
                if(a[j]<a[j-1])
                    swap(a[j],a[j-1]);
    
    
        cout << a[0] <<a[1]<<a[2]<<a[3];
    }
    

【问题讨论】:

  • 案例 1 和 2 似乎相同。您的意思是添加一张不同的图片吗?
  • 请编译代码并查看输出。你应该意识到一些差异。
  • 如果没有理由使用指针,那么就不要使用它们。只有当你喜欢更多的写作和可能的复杂性时,你才绝对应该在这种情况下使用指针。
  • 这绝对是一个太宽泛的问题。请查阅 C++ 书籍、教程或其他学习资源。
  • 请参阅stackoverflow.com/questions/11408825/…,了解有关指针和引用之间差异的一些观点。

标签: c++ function pointers reference function-pointers


【解决方案1】:

您的前两个版本是相同的。它们都显式地传递了一个指向函数的指针。

您的第三个版本具有相同的语义,但语法不同。引用可以看作是语法更好的指针。

你的第四个版本实际上并没有交换你传入的变量,因为你是按值传递的,所以它们被复制了。

我更喜欢第三个版本,因为它更清晰。

【讨论】:

    【解决方案2】:

    一般来说,引用更方便。它们允许程序员通过引用传递对象,而无需明确表示他们想要这样做

    比如这段代码

    // C-style pointers
    some_func(int* x, int* y)
    {
        (*x)++;
        (*y)++;
    }
    
    ...
    
    int x = 5, y = 8;
    some_func(&x, &y);
    // x == 6 and y == 9
    

    实际上等于此代码

    // C++-style references
    some_func(int& x, int& y)
    {
        x++;
        y++;
    }
    
    ...
    
    int x = 5, y = 8;
    some_func(x, y);
    // x == 6 and y == 9
    

    两者都达到相同的结果。

    此外,对于类/结构,引用允许您直接访问类/结构成员,而无需键入那个愚蠢的箭头 (-&gt;):

    class Example
    {
        public:
            Example();
            int x;
            int y;
    }
    
    ...
    
    void do_something(Example& ex)
    {
        ex.x++;
        ex.y++;
    }
    

    而不是

    class Example
    {
        public:
            Example();
            int x;
            int y;
    }
    
    ...
    
    void do_something(Example* ex)
    {
        ex->x++;
        ex->y++;
    }
    

    请注意,以这种方式使用的引用仅是 C++ 功能(C 中不支持此功能)。在 C++ 中,您可以选择使用指针或引用,但恕我直言,引用看起来“更干净”并且需要更少的输入(从而降低 RSI 的风险)。

    【讨论】:

      【解决方案3】:

      我看不出1.2. 之间有什么区别。但总的来说:

      1. 传递指针就是将地址传递给变量。然后您使用取消引用修改此地址下的内容,即*a

      2. 相同。

      3. 是通过引用传递的,它基本上相当于以更好的语法传递指针。当然有一些“小”(从初学者的角度来看)差异,例如,您不能空引用 (nullptr)。

      4. 按值传递,它不对原始操作数进行操作,而是对其副本进行操作。在函数调用时,会制作参数的临时副本。这意味着,您不会看到函数外部参数的更改。

      一般的优先顺序是:

      1. 使用引用,或const 引用。
      2. 如果您仍然需要制作对象的副本,请按值传递。
      3. 智能指针。
      4. 指针。普通用户几乎不需要求助于这个。

      使用引用是首选,因为 c++ 更喜欢值语义。换句话说,处理变量之类的东西,即不是处理程序/指针。因此,当您将变量传递给函数时,您自然会键入它,即使您想更改它。你想使用对象,你传递对象。你不在乎它在后台使用处理程序。

      指针通常保留用于处理对象所有权的操作。

      以这种方式分离指针和引用使得用不同的语法表达不同的语义成为可能。这使代码更具可读性。

      【讨论】:

        【解决方案4】:

        首先,我想指出你不应该使用

        int a[]={1,2,3,4};
        

        在您的代码中,因为即使您的交换功能无法正常工作,您的程序也将始终显示 1234。因此,您应该使用类似

        int a[]={2,4,1,3};
        

        其次,方法一和方法二完全一样。完全没有区别。

        第三,方法4不能正常工作,因为数组'a'中的数据没有被修改。发生这种情况是因为您通过“按值”而不是“按引用”传递变量。您将获得 1234 作为输出,因为这是您分配给数组的内容。

        最后,您唯一的选择是在“方法 1”和“方法 3”之间。

        我建议使用“方法 3”,因为与“方法 1”相比,它更易于使用且不易混淆(和错误)。

        【讨论】:

          【解决方案5】:

          在某些情况下,通过引用传递允许编译器在被调用函数的同一寄存器中保留基于寄存器的变量(而不是将值存储在本地内存中并将地址传递给被调用函数的本地内存) .

          【讨论】:

            猜你喜欢
            • 2019-05-16
            • 2010-09-25
            • 2018-03-07
            • 2019-06-30
            • 2011-12-21
            • 1970-01-01
            • 2014-12-21
            • 2021-09-27
            • 1970-01-01
            相关资源
            最近更新 更多