This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
Are there benefits of passing by pointer over passing by reference in C++?
In both cases, I achieved the result.
So when is one preferred over the other? What are the reasons we use one over the other?
#include <iostream>
using namespace std;
void swap(int* x, int* y)
{
int z = *x;
*x=*y;
*y=z;
}
void swap(int& x, int& y)
{
int z = x;
x=y;
y=z;
}
int main()
{
int a = 45;
int b = 35;
cout<<"Before Swap\n";
cout<<"a="<<a<<" b="<<b<<"\n";
swap(&a,&b);
cout<<"After Swap with pass by pointer\n";
cout<<"a="<<a<<" b="<<b<<"\n";
swap(a,b);
cout<<"After Swap with pass by reference\n";
cout<<"a="<<a<<" b="<<b<<"\n";
}
Output
Before Swap
a=45 b=35
After Swap with pass by pointer
a=35 b=45
After Swap with pass by reference
a=45 b=35
A reference is semantically the following:
T& <=> *(T * const)
const T& <=> *(T const * const)
T&& <=> [no C equivalent] (C++11)
As with other answers, the following from the C++ FAQ is the one-line answer: references when possible, pointers when needed.
An advantage over pointers is that you need explicit casting in order to pass NULL.
It's still possible, though.
Of the compilers I've tested, none emit a warning for the following:
int* p() {
return 0;
}
void x(int& y) {
y = 1;
}
int main() {
x(*p());
}
In fact, most compilers emit the same code for both functions calls, because references are generally implemented using pointers.
Following this logic, when an argument of (non-const) reference type is used in the function body, the generated code will just silently operate on the address of the argument and it will dereference it. In addition, when a call to such a function is encountered, the compiler will generate code that passes the address of the arguments instead of copying their value.
Basically, references and pointers are not very different from an implementation point of view, the main (and very important) difference is in the philosophy: a reference is the object itself, just with a different name.
References have a couple more advantages compared to pointers (e. g. they can't be NULL, so they are safer to use). Consequently, if you can use C++, then passing by reference is generally considered more elegant and it should be preferred. However, in C, there's no passing by reference, so if you want to write C code (or, horribile dictu, code that compiles with both a C and a C++ compiler, albeit that's not a good idea), you'll have to restrict yourself to using pointers.
Pass by pointer is the only way you could pass "by reference" in C, so you still see it used quite a bit.
The NULL pointer is a handy convention for saying a parameter is unused or not valid, so use a pointer in that case.
References can't be updated once they're set, so use a pointer if you ever need to reassign it.
Prefer a reference in every case where there isn't a good reason not to. Make it const if you can.
Here is a good article on the matter - "Use references when you can, and pointers when you have to."
Use references all the time and pointers only when you have to refer to NULL which reference cannot refer.
See this FAQ :
http://www.parashift.com/c++-faq-lite/references.html#faq-8.6
Related
C++ references have two properties:
They always point to the same object.
They can not be 0.
Pointers are the opposite:
They can point to different objects.
They can be 0.
Why is there no "non-nullable, reseatable reference or pointer" in C++? I can't think of a good reason why references shouldn't be reseatable.
Edit:
The question comes up often because I usually use references when I want to make sure that an "association" (I'm avoiding the words "reference" or "pointer" here) is never invalid.
I don't think I ever thought "great that this ref always refers to the same object". If references were reseatable, one could still get the current behavior like this:
int i = 3;
int& const j = i;
This is already legal C++, but meaningless.
I restate my question like this: "What was the rationale behind the 'a reference is the object' design? Why was it considered useful to have references always be the same object, instead of only when declared as const?"
Cheers, Felix
The reason that C++ does not allow you to rebind references is given in Stroustrup's "Design and Evolution of C++" :
It is not possible to change what a reference refers to after initialization. That is, once a C++ reference is initialized it cannot be made to refer to a different object later; it cannot be re-bound. I had in the past been bitten by Algol68 references where r1=r2 can either assign through r1 to the object referred to or assign a new reference value to r1 (re-binding r1) depending on the type of r2. I wanted to avoid such problems in C++.
In C++, it is often said that "the reference is the object". In one sense, it is true: though references are handled as pointers when the source code is compiled, the reference is intended to signify an object that is not copied when a function is called. Since references are not directly addressable (for example, references have no address, & returns the address of the object), it would not semantically make sense to reassign them. Moreover, C++ already has pointers, which handles the semantics of re-setting.
Because then you'd have no reseatable type which can not be 0. Unless, you included 3 types of references/pointers. Which would just complicate the language for very little gain (And then why not add the 4th type too? Non-reseatable reference which can be 0?)
A better question may be, why would you want references to be reseatable? If they were, that would make them less useful in a lot of situations. It would make it harder for the compiler to do alias analysis.
It seems that the main reason references in Java or C# are reseatable is because they do the work of pointers. They point to objects. They are not aliases for an object.
What should the effect of the following be?
int i = 42;
int& j = i;
j = 43;
In C++ today, with non-reseatable references, it is simple. j is an alias for i, and i ends up with the value 43.
If references had been reseatable, then the third line would bind the reference j to a different value. It would no longer alias i, but instead the integer literal 43 (which isn't valid, of course). Or perhaps a simpler (or at least syntactically valid) example:
int i = 42;
int k = 43;
int& j = i;
j = k;
With reseatable references. j would point to k after evaluating this code.
With C++'s non-reseatable references, j still points to i, and i is assigned the value 43.
Making references reseatable changes the semantics of the language. The reference can no longer be an alias for another variable. Instead it becomes a separate type of value, with its own assignment operator. And then one of the most common usages of references would be impossible. And nothing would be gained in exchange. The newly gained functionality for references already existed in the form of pointers. So now we'd have two ways to do the same thing, and no way to do what references in the current C++ language do.
A reference is not a pointer, it may be implemented as a pointer in the background, but its core concept is not equivalent to a pointer. A reference should be looked at like it *is* the object it is referring to. Therefore you cannot change it, and it cannot be NULL.
A pointer is simply a variable that holds a memory address. The pointer itself has a memory address of its own, and inside that memory address it holds another memory address that it is said to point to. A reference is not the same, it does not have an address of its own, and hence it cannot be changed to "hold" another address.
I think the parashift C++ FAQ on references says it best:
Important note: Even though a
reference is often implemented using
an address in the underlying assembly
language, please do not think of a
reference as a funny looking pointer
to an object. A reference is the
object. It is not a pointer to the
object, nor a copy of the object. It
is the object.
and again in FAQ 8.5 :
Unlike a pointer, once a reference is
bound to an object, it can not be
"reseated" to another object. The
reference itself isn't an object (it
has no identity; taking the address of
a reference gives you the address of
the referent; remember: the reference
is its referent).
A reseatable reference would be functionally identical to a pointer.
Concerning nullability: you cannot guarantee that such a "reseatable reference" is non-NULL at compile time, so any such test would have to take place at runtime. You could achieve this yourself by writing a smart pointer-style class template that throws an exception when initialised or assigned NULL:
struct null_pointer_exception { ... };
template<typename T>
struct non_null_pointer {
// No default ctor as it could only sensibly produce a NULL pointer
non_null_pointer(T* p) : _p(p) { die_if_null(); }
non_null_pointer(non_null_pointer const& nnp) : _p(nnp._p) {}
non_null_pointer& operator=(T* p) { _p = p; die_if_null(); }
non_null_pointer& operator=(non_null_pointer const& nnp) { _p = nnp._p; }
T& operator*() { return *_p; }
T const& operator*() const { return *_p; }
T* operator->() { return _p; }
// Allow implicit conversion to T* for convenience
operator T*() const { return _p; }
// You also need to implement operators for +, -, +=, -=, ++, --
private:
T* _p;
void die_if_null() const {
if (!_p) { throw null_pointer_exception(); }
}
};
This might be useful on occasion -- a function taking a non_null_pointer<int> parameter certainly communicates more information to the caller than does a function taking int*.
Intrestingly, many answers here are a bit fuzzy or even beside the point (e.g. it's not because references cannot be zero or similar, in fact, you can easily construct an example where a reference is zero).
The real reason why re-setting a reference is not possible is rather simple.
Pointers enable you to do two things: To change the value behind the pointer (either through the -> or the * operator), and to change the pointer itself (direct assign =). Example:
int a;
int * p = &a;
Changing the value requires dereferencing: *p = 42;
Changing the pointer: p = 0;
References allow you to only change the value. Why? Since there is no other syntax to express the re-set. Example:
int a = 10;
int b = 20;
int & r = a;
r = b; // re-set r to b, or set a to 20?
In other words, it would be ambiguous if you were allowed to re-set a reference. It makes even more sense when passing by reference:
void foo(int & r)
{
int b = 20;
r = b; // re-set r to a? or set a to 20?
}
void main()
{
int a = 10;
foo(a);
}
Hope that helps :-)
It would probably have been less confusing to name C++ references "aliases"? As others have mentioned, references in C++ should be though of as the variable they refer to, not as a pointer/reference to the variable. As such, I can't think of a good reason they should be resettable.
when dealing with pointers, it often makes sense allowing null as a value (and otherwise, you probably want a reference instead). If you specifically want to disallow holding null, you could always code your own smart pointer type ;)
C++ references can sometimes be forced to be 0 with some compilers (it's just a bad idea to do so*, and it violates the standard*).
int &x = *((int*)0); // Illegal but some compilers accept it
EDIT: according to various people who know the standard much better than myself, the above code produces "undefined behavior". In at least some versions of GCC and Visual Studio, I've seen this do the expected thing: the equivalent of setting a pointer to NULL (and causes a NULL pointer exception when accessed).
You can't do this:
int theInt = 0;
int& refToTheInt = theInt;
int otherInt = 42;
refToTheInt = otherInt;
...for the same reason why secondInt and firstInt don't have the same value here:
int firstInt = 1;
int secondInt = 2;
secondInt = firstInt;
firstInt = 3;
assert( firstInt != secondInt );
This is not actually an answer, but a workaround for this limitation.
Basically, when you try to "rebind" a reference you are actually trying to use the same name to refer to a new value in the following context. In C++, this can be achieve by introducing a block scope.
In jalf's example
int i = 42;
int k = 43;
int& j = i;
//change i, or change j?
j = k;
if you want to change i, write it as above. However, if you want to change the meaning of j to mean k, you can do this:
int i = 42;
int k = 43;
int& j = i;
//change i, or change j?
//change j!
{
int& j = k;
//do what ever with j's new meaning
}
I would imagine that it is related to optimization.
Static optimization is much easier when you can know unambiguously what bit of memory a variable means. Pointers break this condition and re-setable reference would too.
Because sometimes things should not be re-pointable. (E.g., the reference to a Singleton.)
Because it's great in a function to know that your argument can't be null.
But mostly, because it allows use to have something that really is a pointer, but which acts like a local value object. C++ tries hard, to quote Stroustrup, to make class instances "do as the ints d". Passing an int by vaue is cheap, because an int fitss into a machine register. Classes are often bigger than ints, and passing them by value has significant overhead.
Being able to pass a pointer (which is often the size of an int, or maybe two ints) that "looks like" a value object allows us to write cleaner code, without the "implementation detail" of dereferences. And, along with operator overloading, it allows us to write classes use syntax similar to the syntax used with ints. In particular, it allows us to write template classes with syntax that can be equally applied to primitive, like ints, and classes (like a Complex number class).
And, with operator overloading especially, there are places were we should return an object, but again, it's much cheaper to return a pointer. Oncve again, returning a reference is our "out.
And pointers are hard. Not for you, maybe, and not to anyone that realizes a pointer is just the value of a memory address. But recalling my CS 101 class, they tripped up a number of students.
char* p = s; *p = *s; *p++ = *s++; i = ++*p;
can be confusing.
Heck, after 40 years of C, people still can't even agree if a pointer declaration should be:
char* p;
or
char *p;
I always wondered why they didn't make a reference assignment operator (say :=) for this.
Just to get on someone's nerves I wrote some code to change the target of a reference in a structure.
No, I do not recommend repeating my trick. It will break if ported to a sufficiently different architecture.
The fact that references in C++ are not nullable is a side-effect of them being just an alias.
I agree with the accepted answer.
But for constness, they behave much like pointers though.
struct A{
int y;
int& x;
A():y(0),x(y){}
};
int main(){
A a;
const A& ar=a;
ar.x++;
}
works.
See
Design reasons for the behavior of reference members of classes passed by const reference
There's a workaround if you want a member variable that's a reference and you want to be able to rebind it. While I find it useful and reliable, note that it uses some (very weak) assumptions on memory layout. It's up to you to decide whether it's within your coding standards.
#include <iostream>
struct Field_a_t
{
int& a_;
Field_a_t(int& a)
: a_(a) {}
Field_a_t& operator=(int& a)
{
// a_.~int(); // do this if you have a non-trivial destructor
new(this)Field_a_t(a);
}
};
struct MyType : Field_a_t
{
char c_;
MyType(int& a, char c)
: Field_a_t(a)
, c_(c) {}
};
int main()
{
int i = 1;
int j = 2;
MyType x(i, 'x');
std::cout << x.a_;
x.a_ = 3;
std::cout << i;
((Field_a_t&)x) = j;
std::cout << x.a_;
x.a_ = 4;
std::cout << j;
}
This is not very efficient as you need a separate type for each reassignable reference field and make them base classes; also, there's a weak assumption here that a class having a single reference type won't have a __vfptr or any other type_id-related field that could potentially destroy runtime bindings of MyType. All the compilers I know satisfy that condition (and it would make little sense not doing so).
Being half serious: IMHO to make them little more different from pointers ;) You know that you can write:
MyClass & c = *new MyClass();
If you could also later write:
c = *new MyClass("other")
would it make sense to have any references alongside with pointers?
MyClass * a = new MyClass();
MyClass & b = *new MyClass();
a = new MyClass("other");
b = *new MyClass("another");
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
How to pass objects to functions in C++?
I am learning about reference parameters and got the following question:
What is the difference between this:
void B(int* worthRef) {
*worthRef += 1;
}
int main() {
int netWorth = 55;
B(&netWorth);
return 0;
}
And this:
void B(int &worthRef) {
worthRef += 1;
}
int main() {
int netWorth = 55;
B(netWorth);
return 0;
}
The first one (int *) passes a pointer-to-integer by value; the second (int &) passes an integer by reference. Both methods can be used to implement abstract "reference semantics", but in C++ you should use actual references when possible.
When you use pointers to implement reference semantics, you pass by value a pointer to the object that you want to refer to, and you dereference the pointer to obtain the actual object reference. In C, where you have no references in the language, that's the only way to implement reference semantics, but in C++ you have actual reference types in the language for this purpose.
Note that passing a pointer can be used a little differently from a reference, since you can pass a null pointer to convey additional semantics, and you can also modify the pointer variable (e.g. for using the local copy of the pointer in the callee scope to traverse an array).
But in a nutshell: Use references. Don't use naked pointers in C++. (To implement reference semantics, you use references, and to implement whatever else naked pointers can be (ab)used for, use the appropriate higher-level idiom.) The fundamental problem with naked pointers is that they convey no ownership semantics, and C++ has many far better tools to write maintainable, local and self-documenting code.
Here you are passing the address of the int:
void B(int* worthRef) {
*worthRef += 1;
}
The parameter is a pointer. The address passed may be 0 (or NULL). Also used in C. The pointer may altered within B: ++worthRef - why you would prefer that...
Here, the implementation takes the address of the parameter:
void B(int &worthRef) {
worthRef += 1;
}
The parameter is a C++ reference. The address passed must not be 0, and may not be altered (of course, what it refers to may be altered if not const, as seen in your example). This is the default written style in most C++ circles. Mechanically, a reference is a bit of syntactic sugar, but it is absolutely useful to convey intent and offer guarantees.
Stylistically, some people prefer the former for parameters which may mutate. I use the latter wherever possible (and legal) -- it's more conventional for C++.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
I got my head around pointers in C (the basics anyway) and started reading up on C++. The book I'm reading jumps straight into references, and looking in the index doesnt got on to pointers until later on.
In C, I thought if I wanted to do a pass by reference function I would have to use pointers as arguments,
e.g.
void swapAandB(int *A, int *B){
//do something
}
But the C++ book, decides to put references to the original variable into the function. e.g.
void swapAandB(int& A, int& B){
//do something
}
My C++ book hasn't explained why we don't use pointers as in C. So I'm a little confused. I guess my question is what's going on here?
References are and additional mechanism that C++ provides compared to C. Using pointers in C++ is perfectly legal, so you could still define your first function unmodified:
void swapAandB(int *A, int *B){
//do something
}
The main advantage that references offer over pointers is that it is not that easy to have the equivalent of a NULL pointer. But, references, both semantically and syntactically go well beyond this in shaping C++ features as a language. I think this will become clearer once you get more into the language. Anyway, you can try and read this paper about the difference between pointers and references.
You can use pointers as in C of course but references are objects aliases, so, the object exist, you don't need to check if their are valid. There are differences with pointers in their use:
void foo(Type * pointer)
{
if (pointer)
pointer->data_ = ....;
}
void foo(Type & reference)
{
reference.data_ = ....;
}
Type obj;
foo(&obj); // pointer syntax
foo(obj); // reference syntax
Besides, a reference always 'point' to the same object, so you will be sure always of using it correctly.
In this case pointers and references will behave the same way.
The only difference is how you call them:
int x, y;
swapAandB( &x, &y ); // here you pass the variables' addresses to the pointer function
swapAandB( x, y ); // here you pass the variables' reference to the reference function
The result is the same, the variables don't get copied, but rather referenced from within the functions, and any changes you apply to them inside the function will affect the variables in the calling scope.
As a rule:
Try to use references instead of pointers.
In some cases you need to use pointers:
polymorphism
you need to have something like a null pointer
you need to delete a variable later on
For example: void foo( int& i ); is not allowed. Is there a reason for this, or was it just not part of the specification? It is my understanding that references are generally implemented as pointers. In C++, is there any functional difference (not syntactic/semantic) between void foo( int* i ) and void foo( int& i )?
Because references are a C++ feature.
References are merely syntactic vinegar for pointers. Their implementation is identical, but they hide the fact that the called function might modify the variable. The only time they actually fill an important role is for making other C++ features possible - operator overloading comes to mind - and depending on your perspective these might also be syntactic vinegar.
For example: void foo( int& i ); is not allowed. Is there a reason for this, or was it just not part of the specification?
It was not a part of the specification. The syntax "type&" for references were introduced in C++.
It is my understanding that references are generally implemented as pointers. In C++, is there any functional difference (not syntactic/semantic) between void foo( int* i ) and void foo( int& i )?
I am not sure if it qualifies as a semantic difference, but references offer better protection against dereferencing nulls.
Because the & operator has only 2 meanings in C:
address of its operand (unary),
and, the bitwise AND operator (binary).
int &i; is not a valid declaration in C.
For a function argument, the difference between pointer and reference is not that big a deal, but in many cases (e.g. member variables) having references substantially limits what you can do, since it cannot be rebound.
References were not present in C. However, C did have what amounts to mutable arguments passed by reference. Example:
int foo(int in, int *out) { return (*out)++ + in; }
// ...
int x = 1; int y = 2;
x = foo(x, &y);
// x == y == 3.
However, it was a common error to forget to dereference "out" in every usage in more complicated foo()s. C++ references allowed a smoother syntax for representing mutable members of the closure. In both languages, this can confound compiler optimizations by having multiple symbols referring to the same storage. (Consider "foo(x,x)". Now it's undefined whether the "++" occurs after only "*out" or also after "in", since there's no sequence point between the two uses and the increment is only required to happen sometime after the value of the left expression is taken.)
But additionally, explicit references disambiguate two cases to a C++ compiler. A pointer passed into a C function could be a mutable argument or a pointer to an array (or many other things, but these two adequately illustrate the ambiguity). Contrast "char *x" and "char *y". (... or fail to do so, as expected.) A variable passed by reference into a C++ function is unambiguously a mutable member of the closure. If for instance we had
// in class baz's scope
private: int bar(int &x, int &y) {return x - y};
public : int foo(int &x, int &y) {return x + bar(x,y);}
// exit scope and wander on ...
int a = 1; int b = 2; baz c;
a = c.foo(a,b);
We know several things:
bar() is only called from foo(). This means bar() can be compiled so that its two arguments are found in foo()'s stack frame instead of it's own. It's called copy elision and it's a great thing.
Copy elision gets even more exciting when a function is of the form "T &foo(T &)", the compiler knows a temporary is going in and coming out, and the compiler can infer that the result can be constructed in place of the argument. Then no copying of the temporary in or the result out need be compiled in. foo() can be compiled to get its argument from some enclosing stack frame and write its result directly to some enclosing stack frame.
a recent article about copy elision and (surprise) it works even better if you pass by value in modern compilers (and how rvalue references in C++0x will help the compilers skip even more pointless copies), see http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ .
I was studying pointers references and came across different ways to feed in parameters. Can someone explain what each one actually means?
I think the first one is simple, it's that x is a copy of the parameter fed in so another variable is created on the stack.
As for the others I'm clueless.
void doSomething1(int x){
//code
}
void doSomething2(int *x){
//code
}
void doSomething3(int &x){
//code
}
void doSomething3(int const &x){
//code
}
I also see stuff like this when variables are declared. I don't understand the differences between them. I know that the first one will put 100 into the variable y on the stack. It won't create a new address or anything.
//example 1
int y = 100;
//example 2
int *y = 100;
//Example 3: epic confusion!
int *y = &z;
Question 1: How do I use these methods? When is it most appropriate?
Question 2: When do I declare variables in that way?
Examples would be great.
P.S. this is one the main reasons I didn't learn C++ as Java just has garbage collection. But now I have to get into C++.
//example 1
int y = 100;
//example 2
int *y = 100;
//Example 3: epic confusion!
int *y = &z;
I think the problem for most students is that in C++ both & and * have different meanings, depending on the context in which they are used.
If either of them appears after a type within an object declaration (T* or T&), they are type modifiers and change the type from plain T to a reference to a T (T&) or a pointer to a T (T*).
If they appear in front of an object (&obj or *obj), they are unary prefix operators invoked on the object. The prefix & returns the address of the object it is invoked for, * dereferences a pointer, iterator etc., yielding the value it references.
It doesn't help against confusion that the type modifiers apply to the object being declared, not the type. That is, T* a, b; defines a T* named a and a plain T named b, which is why many people prefer to write T *a, b; instead (note the placement of the type-modifying * adjacent the object being defined, instead of the type modified).
Also unhelpful is that the term "reference" is overloaded. For one thing it means a syntactic construct, as in T&. But there's also the broader meaning of a "reference" being something that refers to something else. In this sense, both a pointer T* and a reference (other meaning T&) are references, in that they reference some object. That comes into play when someone says that "a pointer references some object" or that a pointer is "dereferenced".
So in your specific cases, #1 defines a plain int, #2 defines a pointer to an int and initializes it with the address 100 (whatever lives there is probably best left untouched ), and #3 defines another pointer and initializes it with the address of an object z (necessarily an int, too).
A for how to pass objects to functions in C++, here is an old answer from me to that.
From Scott Myers - More Effective C++ -> 1
First, recognize that there is no such thing as a null reference. A reference must always refer to some object.Because a reference must refer to an object, C++ requires that references be initialized.
Pointers are subject to no such restriction. The fact that there is no such thing as a null reference implies that it can be more efficient to use references than to use pointers. That's because there's no need to test the validity of a reference before using it.
Another important difference between pointers and references is that pointers may be reassigned to refer to different objects. A reference, however, always refers to the object with which it is initialized
In general, you should use a pointer whenever you need to take into account the possibility that there's nothing to refer to (in which case you can set the pointer to null) or whenever you need to be able to refer to different things at different times (in which case you can change where the pointer points). You should use a reference whenever you know there will always be an object to refer to and you also know that once you're referring to that object, you'll never want to refer to anything else.
References, then, are the feature of choice when you know you have something to refer to, when you'll never want to refer to anything else, and when implementing operators whose syntactic requirements make the use of pointers undesirable. In all other cases, stick with pointers.
Read S.Lippmann's C++ Premier or any other good C++ book.
As for passing the parameters, generally when copying is cheap we pass by value. For mandatory out parameters we use references, for optional out parameters - pointers, for input parameters where copying is costly, we pass by const references
Thats really complicated topic. Please read here: http://www.goingware.com/tips/parameters/.
Also Scott Meiers "Effective C++" is a top book on such things.
void doSomething1(int x){
//code
}
This one pass the variable by value, whatever happens inside the function, the original variable doesn't change
void doSomething2(int *x){
//code
}
Here you pass a variable of type pointer to integer. So when accessing the number you should use *x for the value or x for the address
void doSomething3(int &x){
//code
}
Here is like the first one, but whatever happens inside the function, the original variable will be changed as well
int y = 100;
normal integer
//example 2
int *y = 100;
pointer to address 100
//Example 3: epic confusion!
int *y = &z;
pointer to the address of z
void doSomething1(int x){
//code
}
void doSomething2(int *x){
//code
}
void doSomething3(int &x){
//code
}
And i am really getting confused between them?
The first is using pass-by-value and the argument to the function will retain its original value after the call.
The later two are using pass-by-reference. Essentially they are two ways of achieving the same thing. The argument is not guarenteed to retain its original value after the call.
Most programmers prefer to pass large objects by const reference to improve the performance of their code and provide a constraint that the value will not change. This ensures the copy constructor is not called.
Your confusion might be due to the '&' operator having two meanings. The one you seem to be familiar with is the 'reference operator'. It is also used as the 'address operator'. In the example you give you are taking the address of z.
A good book to check out that covers all of this in detail is 'Accelerated C++' by Andrew Koening.
The best time to use those methods is when it's more efficient to pass around references as opposed to entire objects. Sometimes, some data structure operations are also faster using references (inserting into a linked list for example). The best way to understand pointers is to read about them and then write programs to use them (and compare them to their pass-by-value counterparts).
And for the record, knowledge of pointers makes you considerably more valuable in the workplace. (all too often, C++ programmers are the "mystics" of the office, with knowledge of how those magical boxes under the desks process code /semi-sarcasm)