I'm looking few exercise from university about C++ and I found out this exercise:
#include <iostream>
using namespace std;
int& f(int*&);
int& f(int*& x) {
*x = 5;
return *x;
}
int main() {
int y = 1, x;
int* z = &y;
x= f(z);
cout << y << " " << x <<endl;
}
I was wondering: does <any type>*& has any real sense? Isn't f(int*& x) the same as f(int x)? Aren't you passing the pointer to the L-value of the variable?
f(int*& x) is not the same as f(int x). In the first case x is a reference to an integer pointer whereas in the second case x is just an integer.
Lets start from the basics:
When you write f(int &x) means that x is a reference to an integer and you can change the value of x in the function and the change will be reflected in the calling function.
Similarly, when you write f(int*& x), it means that x is reference to an integer pointer and when you change the address that x points to, the change will also be reflected in the calling function.
With int* &x you are passing the same pointer(by reference). Otherwise with only int* x you are passing a copy of the pointer and then you can't change the original one in the function. &x makes x an alias of the original parameter.
It's a reference to a pointer to an int. The function is then able to change the pointer if it wants to. In your example it doesn't make sense, but it obviously does have a use.
nope: *& here doesn't mean "dereference addressof". It means: "pass a pointer byref".
int& f(int*& x) {
*x = 5; // note: changes the pointee, not the pointer
return *x;
}
In this example, you don't gain anything by passing the pointer by reference, since you're not changing the pointer. Passing a pointer by reference is only needed when you intend to change the pointer:
void f(int*& x) {
x = new int(42); // note: changes the pointer
}
I think you are confusing sybols when they are used as operators or declarators.
If you use * when declaring variable, that means veriable is a pointer. When you use * as operator, that is dereference operator.
int *& name
simply means you are taking pointer to int by reference. **The * and & do not cancel each other out.**
If you had line of code like this:
var = *& var2;
then yes, it would be same as:
var = var2;
Related
Why are reference variable are considered as pointer in parameter passing?
int x;
void fun(&x);
void fun(int* y)
{
------some code----
}
Here, reference of variable x is passed to fun() function. Local variable y in fun() contains reference of variable x but y is declared as pointer. Why?
You're mistaken &x is not a 'reference variable'. It is a pointer to x, & is the address-of operator, which returns the address (i.e. a pointer) of whatever argument it's given.
It's confusing because & is used to mean a reference in type declarations but it's meaning in expressions is different.
For example
int x;
int& y = x; // here & means reference because 'int&' is a type declaration
int* z = &x; // here & means address-of because '&x' is an expression
void fun(&x);
in this line &x is "not reference variable", that is address of x variable.
Example:
int y ;
int &z = y; // here &z is reference variable(a reference must initialized when it is created)
Here: void fun(&x);
You are passing the address (and not a reference) of variable x to void fun(int* y).
Since int* y is a pointer, it then points to the address of x.
I am reading through Stroustrup's 4th edition : The C++ Programming Language. I have a python/java background so the first 4 chapters are fine so far.
In Chapter 3 I saw:
complex& operator+=(complex z) { re+=z.re , im+=z.im; return ∗this; }
That began a day long attempt to write this question:
First I figured out that it is returning a reference to the object and not a copy. As I was able to confirm in this question.
And I was able to understand the difference between returning a reference into a reference variable vs. a regular variable from this question
And I did my own trial
class Test {
public:
Test():x{5}{}
int x;
void setX(int a) {x = a;}
Test& operator+=(Test z) {x+=z.x; return *this;}
// the keyword this is a pointer
Test* getTest() {return this;}
// but I can return the reference by *this
Test& getTest1() {return *this;}
// or I can return a copy
Test getTest2() {return *this;}
};
That lead me to question why it is called de-reference, so I did this trial
int x = 8;
int* p = &x;
int y = *p;
int& z = *p;
x++; // let's have some fun
std::cout << y << std::endl;
std::cout << z << std::endl;
As expected y = 8 and z = 9, so how did the de-reference return the address in one case, and the value in the other? More importantly how is C++ making that distinction?
It's exactly like in your Test class functions.
int y = *p;
int& z = *p;
y is a copy of what p points to.
z is a reference to (not an address) what p points to. So changing z changes *p and vice-versa. But changing y has no effect on *p.
As expected y = 8 and z = 9, so how did the de-reference return the address in one case, and the value in the other? More importantly how is C++ making that distinction?
The de-reference returned the actual thing referenced in both cases. So there is no distinction for C++ to make. The difference is in what was done with the result of the dereference.
If you do int j = <something>; then the result of the something is used to initialize j. Since j is an integer, the <something> must be an integer value.
If you do int &j = <something>; then the result of the something is still used to initialize j. But now, j is a reference to an integer, and the <something> must be an integer, not just an integer value.
So, what *this does is the same in both cases. How you use a value doesn't affect how that value is computed. But how you use it does affect what happens when you use it. And these two pieces of code use the dereferenced object differently. In one case, its value is taken. In the other case, a reference is bound to it.
It's possible to consider a pointer int* p as pointing to an address where data of type int resides. When you de-reference this, the system retrieves the value at that memory address (the address is the actual value of p itself). In the case of int y = *p; you put a copy of that int value on the stack as the locator value y.
On the other hand, de-referencing on the left-hand side in *p = 13; means you are replacing the int value *p stored at the memory address denoted by the value of p with the right-hand-side value 13.
The reference lvalue int& z in int& z = *p; is not a copy of the int value pointed to by p but rather a left-hand side reference to whatever is at the particular memory address returned by *p (i.e. the actual value held by p itself).
This doesn't mean much difference in your contrived case, but e.g. given a Foo class with a Foo::incrementCount() value,
Foo* p = new Foo();
p->incrementCount();
Foo& ref = *p;
ref.incrementCount();
The same method for the same instance will be called twice. In contrast, Foo foo = *p will actually copy the entire Foo instance, creating a separate copy on the stack. Thus, calling foo.incrementValue() won't affect the separate object still pointed to by p.
For example, if F is a reference to an integer, where the reference is not permitted to be pointed to a new object once it is initially pointed to one.
Can I write to declaration like: const int & F?
I am confused about reference and pointer, because they both represent the address of something, but we always write parameter use reference as: const & F, I understand that this is to reduce the copy and does not allow others to change it, but are there any other meanings? and why do we need "const" after a function declaration like: int F(int z) const; this const makes the return type const or everything in the function const?
One more example,
void F(int* p)
{
p+=3;
}
int z=8;
F(&z);
std::cout<<z<<std::endl;
What is the output for z since z is a reference, and I pass it as a pointer who points to an integer.Increasing p by 3 just makes the address different and does not change its value?
Just a first pass at some answers - if anything is unclear please comment and I'll try to elaborate.
int a = 3;
declares an integer, a, with the initial value 3, but you are allowed to change it. For example, later you can do
a = 5; // (*)
and a will have the value 5. If you want to prevent this, you can instead write
const int a = 3;
which will make the assignment (*) illegal - the compiler will issue an error.
If you create a reference to an integer, you are basically creating an alias:
int& b = a;
, despite appearances, does not create a new integer b. Instead, it declares b as an alias for a. If a had the value 3 before, so will b, if you write b = 6 and print the value of a, you will get 6 as well. Just as for a, you can make the assignment b = 6 illegal by declaring it as const:
const int& b = a;
means that b is still an alias for a, but it will not be used to assign a different value to a. It will only be used to read the value of a. Note that a itself still may or may not be constant - if you declared it as non-const you can still write a = 6 and b will also be 6.
As for the question about the pointers: the snippet
void F(int* p) {
p += 3;
}
int z = 8;
F(&z);
does not do what you expected. You pass the address of z into the function F, so inside F, the pointer p will point to z. However, what you are doing then, is adding 3 to the value of p, i.e. to the address that p points to. So you will change to pointer to point at some (semi)random memory address. Luckily, it's just a copy, and it will be discarded. What you probably wanted to do, is increment the value of the integer that p points to, which would be *p += 3. You could have prevented this mistake by making the argument a int* const, meaning: the value of p (i.e. address pointed to) cannot be changed, but the value it points to (i.e. the value of z, in this case) can. This would have made *p += 3 legal but not the "erroneous" (unintended) p += 3. Other versions would be const int* p which would make p += 3 legal but not *p += 3, and const int* const` which would have allowed neither.
Actually, the way you have written F is dangerous: suppose that you expand the function and later you write (correctly) *p += 3. You think that you are updating the value of z whose address you passed in, while actually you are updating the value of a more-or-less random memory address. In fact, when I tried compiling the following:
// WARNING WARNING WARNING
// DANGEROUS CODE - This will probably produce a segfault - don't run it!
void F(int* p) {
p += 3; // I thought I wrote *p += 3
// ... Lots of other code in between, I forgot I accidentally changed p
*p += 3; // NOOOOOOOOOOO!
}
int main()
{
int z=8;
F(&z);
std::cout << z;
return 0;
}
I got a segmentation fault, because I'm writing at an address where I haven't allocated a variable (for all I know I could have just screwed up my boot sector).
Finally, about const after a function declaration: it makes the this pointer a const pointer - basically the compiler emits const A* this instead of just A* this. Conceptually, it states your intention that the function will not change the state of the class, which usually means it won't change any of the (internal) variables. For example, it would make the following code illegal:
class A {
int a;
void f() const {
a = 3; // f is const, so it cannot change a!
}
};
A a;
a.f();
Of course, if the function returns something, this value can have its own type, for example
void f();
int f();
int& f();
const int f();
const int& f();
are functions that return nothing, a (copy of) an integer, a (reference to) an integer, a constant (copy of) an integer, and a constant reference of an integer. If in addition f is guaranteed not to change any class fields, you can also add const after the brackets:
void f() const;
int f() const;
int& f() const;
const int f() const;
const int& f() const;
The way I remember the difference between references and pointers is that a reference must exist and the reference cannot change.
A pointer can be changed, and usually needs to be checked against NULL or tested to verify it points to a valid object.
Also, an object passed by reference can be treated syntactically like it was declared in the function. Pointers must use deferencing syntax.
Hope that helps.
You are confusing things.
First of all int z=8; F(&z); here z IS NOT a reference.
So let me start with the basics:
when found in a type declaration the symbol & denotes a reference, but in any other context, the symbol & means address of.
Similar, in a type declaration * has the meaning of declaring a pointer, anywhere else it it the dereferencing operator, denoting you use the value at an address.
For instance:
int *p : p is a pointer of type int.
x = *p : x is assigned the value found at address p.
int &r = a : r is reference of type int, and r refers the variable a.
p = &a : p is assigned the address of variable a.
Another question you have: the const at the end of a function, like int f(int x) const. This can be used only on non-static class methods and specifies that the function does not modify the object. It has nothing to do with the return value.
until there I trusted that method like
bool solverMethod::buildSimplex(double** simplex_ , double* funcEvals_, double* initPt_)
{
// things
}
would change values for simplex, funcEvals_, initPt_ in the method where it is called (passage by pointer). Am I wrong? How to put it then?
thanks and regards and apologizes for simple question.
This is maybe not as much an answer as it is a general explanation of pointers, references and reference semantics.
A function is said to have reference semantics if it can change the argument objects that are passed to it. For example, the following swap function has reference semantics if it exchanges the values:
int x = 4;
int y = 8;
swap(x, y);
assert(x == 8 && y == 4);
The question is how you implement reference semantics. C++ has a native reference type that makes this very natural:
void swap(int & a, int & b) { int t = a; a = b; b = t; }
By contrast, C does not have such a native feature, and every object in C is passed by value. However, C has a different feature that can be used to implement reference semantics, namely pointers: For every type T, there is a related type T*, a value of which can be obtained by taking the address-of an object of type T: int x; int * p = &x;. Now you can pass those pointer objects around by value and use them to access the original object to which they point. Notice that we are passing the pointers by value!
void c_swap(int * p, int * q) { int t = *p; *p = *q; *q = t; }
We have to call the function differently: swap(&x, &y). Thus in C you can always tell whether an argument is being modified, because the only way to do this is by passing its address to a function. In C++, you have to know the actual function signature to know whether reference or value semantics are in place.
I typed the following example:
#include <iostream>
double f(double* x, double* y)
{
std::cout << "val x: " << *x << "\n";
std::cout << "val y: " << *y << "\n";
return *x * *y;
}
double f2(double &x, double &y)
{
std::cout << "val x: " << x << "\n";
std::cout << "val y: " << y << "\n";
return x * y;
}
int main()
{
double a, b;
a = 2;
b = 3;
std::cout << f(&a, &b) << "\n";
std::cout << f2(a, b) << "\n";
return 0;
}
In the function f I declare x and y as pointers of which I can get the value by using *x. When calling f I need to pass the address of my passed arguments, that is why I pass &a, &b. f2 is the same except the definition is different.
Now my question is: Are they both really the same concerning memory management? Both not making any copy of the passed value but instead passing a reference?
I wonder about f2 because I couldn't read out the address of x in f2 so I know more about x and y in f (there I know address AND value).
Edit: After doing some more research, I found a quite useful topic:
Pointer vs. Reference
There's also a link to google coding guidelines http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments which is quite useful I feel (as I understood now, it's a form of subject taste) to make more clear
f2 is taking it's arguments by reference, which is essentially an alias for the arguments you pass. The difference between pointer and reference is that a reference cannot be NULL. With the f you need to pass the address (using & operator) of the parameters you're passing to the pointer, where when you pass by reference you just pass the parameters and the alias is created.
Passing by const reference (const double& ref) is preferred when you are not going to change the arguments inside the function, and when you are going to change them, use non-const reference.
Pointers are mostly used when you need to be able to pass NULL to your parameters, obviously you'd need to check then inside your function if the pointer was not NULL before using it.
This is just syntactic sugar to avoid having to use * everytime you reference the argument. You still can use & to have the address of x in f2.
In my head, parameters of functions are always passed by value. Passing an int is easy to imagine, passing a double is just bigger and passing a struct or class could be very big indeed.
But passing a pointer to something, well, you're just passing an address by value. (A pointer is often a convenient size for the CPU just like an int.)
A reference is very similar, and certainly I think of a reference as a pointer, but with syntactic sugar to make it look like the object its referring to has been passed by value.
You can also think of a reference as a const pointer, ie:
int i;
int j;
int* p = &i; // pointer to i
int* const cp = p; // cp points to i, but cp cannot be modified
p = &j; // OK - p is modified to point to j
*cp = 0; // OK - i is overwritten
cp = &j; // ERROR - cp cannot be modified
int& ri = i; // ri refers to i
ri = 1; // i is overwritten
ri = j; // i is overwritten again
// Did you think ri might refer to j?
So, a pointer does double time: It is a value in its own right, but it can also point to another value when you dereference it, eg: *p.
Also, having reference parameters means that you cannot make them refer to anything else during the lifetime of the function because there's no way to express that.
A reference is supposed not to be able to be initialised with null, but consider this:
void foo(int& i);
int* p = 0;
foo(*p);
This means that pointers should be checked before you use them, but references cannot be checked. The implementation of foo() could try to read from or write to i which will cause an access violation.
In the above example the pointer p should have been checked before being used in the call to foo:
if (p) foo(*p);
Another difference that hasn't been mentioned is that you cannot change what a reference refers to. This doesn't make a lot of difference in the function call example shown in the original question.
int X(10), Y(20);
int *pX = X;
int& rY = Y;
*pX = 15; // change value of X
rY = 25; // change value of Y
pX = Y; // pX now points to Y
rY always points to Y and cannot be moved.
References can't be used to index into simple arrays like pointers.
You should have been able to read x address in both functions.
To do so in f2, you must of course prefix x by a & since there, x is a reference to a double, and you want an address.
A worth noticing difference between references and pointers is that the former cannot be NULL. You must pass something (valid) while when providing a pointer, you must specify in the documentation if passing NULL is allowed/well defined.
Another difference is a matter of readability: using references instead of pointers (when possible) makes the code less cluttered with * and ->.