Wing Yan Yeung
Wing Yan Yeung

Reputation: 69

What's the difference between using * and using & in C++ functions?

I am trying to find out using the below code with sort an array in asscending order. And I find method 1,2,3,4 all get the same result:1234.

Which method is the best?

And when and why should should I use pointer /reference? Thanks you.

  1. Using & to call, and * in function parameter

  2. Just used * in function parameter

enter image description here

  1. Just used & in function parameter

    enter image description here

  2. nothing:

    #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];
    }
    

Upvotes: 0

Views: 6712

Answers (5)

rcgldr
rcgldr

Reputation: 28828

In some cases, passing by reference allows the compiler to keep a register based variable in that same register in the called function (as opposed to storing the value in local memory and passing an address to that local memory to the called function).

Upvotes: 0

user4834286
user4834286

Reputation:

First of all, I would like to point out that you shouldn't have used

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

in your code, because your program will always display 1234 even if your swap function does not work well. Therefore, you should use something like

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

Secondly, method 1 and method 2 are exactly same. There's no difference at all.

Thirdly, method 4 does not work properly, because the data in the array 'a' hasn't been modified. This happens because you have passed the variables 'by value' rather than 'by reference'. You are getting 1234 as output because that's what you have assigned to the array.

Finally, the only choice you have is between 'method 1' and 'method 3'.

I would suggest 'method 3' because it is simpler to use and less prone to confusion (and errors) as compared to 'method 1'.

Upvotes: 0

luk32
luk32

Reputation: 16070

I don't see a difference between 1. and 2.. But in general:

  1. Passing pointers is passing an address to a variable. Then you modify something under this address using dereference i.e. *a.

  2. Same.

  3. Is passing via reference, it is basically equivalent of passing pointers with nicer syntax. There are of course some "minor" (from a beginner's point of view) differences, such as, you cannot make an empty reference (nullptr).

  4. Is passing by value, which does not operate on original operands but on their copies. At the function call, temporary copies of arguments are made. This means, you won't see changes to the argument outside of the function.

The general order of preference is:

  1. Use references, or const references.
  2. If you need to make a copy of the object anyways, pass by value.
  3. Smart pointers.
  4. Pointers. Normal user should almost never need to resort to this.

Using references is preferred, because c++ prefers value-semantics. In other words, treating things like variables, i.e. not handlers/pointers. So when you pass a variable to a function, you type it naturally, even if you want to change it. You want to use the object, you pass the object. You don't care that under the hood it uses handlers.

Pointers are generally reserved for operations which deal with ownership of objects.

Separating pointers and references in such way makes it possible to express separate semantics with separate syntax. This makes code more readable.

Upvotes: 1

Levi
Levi

Reputation: 1983

Generally, references are more of a convenience thing. They allow the programmer to pass objects by reference without explicitly saying they want to do so

For example, this code

// 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

Is effectively equal to this code

// 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

Both achieve the same result.

Also, in the case with classes/structs, references allow you to have direct access to class/struct members without having to type that stupid arrow (->):

class Example
{
    public:
        Example();
        int x;
        int y;
}

...

void do_something(Example& ex)
{
    ex.x++;
    ex.y++;
}

instead of

class Example
{
    public:
        Example();
        int x;
        int y;
}

...

void do_something(Example* ex)
{
    ex->x++;
    ex->y++;
}

Please note that references used in this manner are a C++ feature only (there is no support for this in C). In C++ you have the choice of using either pointers or references, but IMHO references look 'cleaner' and require less typing (thus reducing the risk of RSI).

Upvotes: 1

TartanLlama
TartanLlama

Reputation: 65620

Your first two versions are identical. They both explicitly pass a pointer in to the function.

Your third version has the same semantics, but different syntax. References can be seen as pointers with nicer syntax.

Your fourth version doesn't actually swap the variables you pass in because you pass by value, so they are copied.

I would prefer the third version as it is clearer.

Upvotes: 2

Related Questions