views:

462

answers:

9

In the following code, both amp_swap() and star_swap() seems to be doing the same thing. So why will someone prefer to use one over the other? Which one is the preferred notation and why? Or is it just a matter of taste?

#include <iostream>

using namespace std;

void amp_swap(int &x, int &y)
{
    int temp = x;
    x = y;
    y = temp;
}

void star_swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main()
{
    int a = 10, b = 20;
    cout << "Using amp_swap(): " << endl;
    amp_swap(a, b);
    cout << "a = " << a << ", b = " << b << endl;
    cout << "Using star_swap(): " << endl;
    star_swap(&a, &b);
    cout << "a = " << a << ", b = " << b << endl;
    return 0;
}

Thanks for your time!


See Also

Difference between pointer variable and reference variable in C++

A: 

They are the exact same thing to the computer. However, one is a reference (&) and the other is a pointer (*)

http://www.google.com/search?hl=en&amp;q=pointers+vs+references&amp;btnG=Google+Search&amp;aq=1&amp;oq=pointers+vs

I believe they both have their uses - as with pointers you can do more low level memory manipulation but the syntax for references is easier.

:)

nlaq
A: 

(int *param) is the older C style, using a direct memory pointer. (int &param) is modern C++ style, using a reference (a type-safe wrapper around raw pointer). If you're using C++, you should probably use a reference.

John Millikin
+12  A: 

One is using a reference, one is using a pointer.

I would use the one with references, because you can't pass a NULL reference (whereas you can pass a NULL pointer).

So if you do:

star_swap(NULL, NULL);

Your application will crash. Whereas if you try:

amp_swap(NULL, NULL); // This won't compile

Always go with references unless you've got a good reason to use a pointer.

See this link:

http://www.google.co.uk/search?q=references+vs+pointers

Mark Ingram
That is not the whole story, all you are saying is that passing by references means you can't pass NULL. This may be true but it's not the whole of what references are.
PintSizedCat
No, but I didn't say it was a complete, consise article on what references are. I was just indicating the biggest differences affecting the provided source code. For the OP, I would recommend reading some articles on what references are.
Mark Ingram
+2  A: 

References cannot be NULL. So, using the first version would prevent a caller from passing NULL as one of the function arguments.

References cannot be reassigned to point to something else. So, you know that within the function amp_swap(), that x and y always refer to the same thing. In the pointer version, you could (in a more complex function) reassign x and y to point to something else, which could make the logic less clear (yes, you could declare the parameters as int *const x to avoid this reassignment).

The function body for the reference version looks cleaner because it doesn't have as many stars.

Greg Hewgill
+1  A: 

This is not a matter of notation.

There are 3 ways to pass parameters to a function: 1. By value 2. By reference 3. By pointers

In "amp_swap" you pass the actual parameters by reference. This is introduced and valid in C++ only.

In amp_star you pass the parameters using pointers. This was the original C-way.

Basically, if you are using C++, it is encouraged to use reference, since it is more readable for variables. If you need pointers, by all means use them.

And remember to use the "&" sign when declaring the method with references, because otherwise you produce a bug. If you don't declare the reference in "amp_swap", the function will not swap anything. Because this way you use method 1. - pass the parameter values only and in the function will be created two new automatic variables, which live only in the scope of the function. This way the original outer variables will not be touched.

m_pGladiator
+1  A: 

If you look here you can find a description of Pointer vs Reference, the most useful bit of information initially comes form this quotation.

C++ doesn't let you declare a "const reference" because a reference is inherently > const. In other words, once you bind a reference to refer to an object, you cannot rebind it to refer to a different object. There's no notation for rebinding a reference after you've declared the reference.

The following binds ri to refer to i.

int &ri = i;

Then an assignment such as:

ri = j;

will not bind ri to j. It will assign the value in j to the object referenced by ri, namely, i.

Hope this is clearer.

PintSizedCat
+3  A: 

An argument can also be made for preferring the pointer version over the reference version. In fact, from a documentation point of view it's superior because the caller is made aware of the fact that the input arguments are going to be modified; compare these two calls:

swap(a, b);
swap(&a, &b); // This cries “will modify arguments” loud and clear.

Of course, in the case of the swap function this point is moot; everybody knows its arguments will be modified. There are other cases where this is less obvious. C# has the ref keyword for exactly this reason. In C#, the above would have to look like this:

swap(ref a, ref b);

Of course, there are other ways to document this behaviour. Using pointers is one valid technique of doing so.

Konrad Rudolph
Interesting point :)
artknish
I disagree somewhat: If you use, or read code using the function "doSomething", then you are supposed to know its interface/contract. Your version, i.e. use of pointer, is just enabling a coder to avoid reading the function's prototype, at the price of enabling passing a NULL pointer.
paercebal
I also disagree with this mentality. the name of the function can make it just as clear. "swap" tells me that it is *swapping* something. Which screams "will modify args" just as clearly.
Evan Teran
+1  A: 
  • Like the pointer, the reference enables the modification of the data passed as a parameter
  • Like the pointer, the reference enables polymorphism
  • Unlike the pointer, the reference is never NULL (you can still achieve this with some hack, but, this is more akin to sabotaging than coding...)
  • Unlike the pointer, the reference, when const, enable type promotion (i.e, having a function with a std::string parameter accepting a char *)
  • Unlike the pointer, the reference cannot be re-assigned: There is no way to have it modified at some point of the code, whereas a pointer can point to A at one point, B at another, and NULL at another again. And you don't want to have ++ applied to your pointer by error...
  • Unlike the pointer, the reference makes the manipulation of the data as easy as it would be with a primitive like "int" or "bool", without using the * operator all the time

For these reasons, in C++, the reference use is usually a default, and the pointer is the exception.

So, for consistency sake, between the two "swap" functions you propose, I would use the amp_swap and remove the star one from the sources (just to be sure no one would use it and add useless pointer code in the sources)...

paercebal