This question already has answers here:
Pointer vs. Reference
(12 answers)
Closed 6 years ago.
I found these two different sources, but they do the exact same thing. I was wondering if there is a difference or not but I couldn't figure it out.
Can anyone tell me the difference and when should I use which?
this is the first one:
void function1(int *x) {
*x = 100;
}
int main() {
int var1 = 10;
function1(&var1);
cout << var1 << endl;
}
and this is the second one:
void function2(int &x) {
x = 100;
}
int main() {
int var2 = 10;
function2(var2);
cout << var2 << endl;
}
int *x is a pointer whereas int &x is a reference. Probably the biggest difference is that you can't change where reference is pointing to.
The first is a pointer, the second is a reference. The ideas have some similarities, but there are also differences.
A pointer is a C and C++ mechanism and a bit more "pure" but gives you more posibilies for advanced concepts like pointer arithmetics. References are C++ only and are more safe and more implicit, as a reference is used with the same syntax as a normal varible while using the referenced one. A pointer is more explicit if you want to use or change its value, as you have to explicitely dereference it using *var, and explicitely have obtain it.
Related
This question already has answers here:
Why are references not reseatable in C++
(17 answers)
Closed 7 years ago.
According to these links: stackoverflow question and C++ FQA references cannot refer to another object/ variable well once they're initialized, but what about the below code?
// Example program in C++
#include <iostream>
using namespace std;
int main()
{
int x=10, z=12;
int &y=x;
++y;
y=z; //valid?
cout << x << ", "<< y <<", " << z << endl; // prints 12, 12, 12
return 0;
}
Below is the C code regarding pointer reseating and it seems valid, am I right?
#include <stdio.h>
int main(int argc, char *argv[])
{
int a=10, b=20;
int *ptr;
ptr = &a;
ptr = &b;
printf("%d\n",a); // prints 10
printf("%d\n",*ptr); // prints 20
return 0;
}
Can someone clear the above concept in the above two codes?
y=z; //valid?
Absolutely! However, it does not mean "y refers to z from now on". It means "set the value of z to whatever y is currently referring", which is x. Hence, y=z is another way of writing x=z.
Below is the C code regarding pointer reseating and it seems valid, am I right?
Unlike references, pointers can be re-pointed, so the re-assignment of the pointer makes it point to a different variable. Your program does not illustrate this, however, because two assignments to ptr happen without any reads of ptr in between, so only the second assignment stays.
In y=z
Its not refering to another variable its just assigning the value of z to y which is 12 and since y is reference to x, x also gets assigned value 12.
so x=y=z=12
But in pointers its valid to change the address it points to:
ptr = &a;
ptr = &b; //valid
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
The code snippet is as follows
#include <iostream>
using namespace std;
int a(int m)
{
return ++m;
}
int b(int &m)
{
return ++m;
}
int c(int &m)
{
return ++m;
}
int main(void)
{
int p=0,q=0,r=0;
p+=a(b(p));
q+=b(a(q));
r+=a(c(r));
cout<<p<<q<<r;
return 0;
}
The error occurring is invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int' at q+=b(a(q)). How to go about the error so that this program prints a desired output
Timothy J Williams is one or both of the following things:
wrong;
teaching C++ as it pertains to Visual Studio only, without disclaiming it, which is ill-advised.
References cannot bind to temporaries. It is not allowed in C++. Visual Studio allows it as a non-standard extension, but that's it. Some people get confused and think that means it's valid C++. It's not.
You will have to store the results of function calls like b(1) into named variables before you pass them anywhere by reference.
int main()
{
int p = 0, q = 0, r = 0;
int result_of_b_p = b(p);
p += a(result_of_b_p);
int result_of_a_q = a(q);
q += b(result_of_a_q);
int result_of_c_r = c(r);
r += a(result_of_c_r);
std::cout << p << q << r << '\n';
}
I should also note that the cited code is confusing and appears to serve no purpose other than for contrived "test your knowledge" challenges. I'd pay not too much attention to this and instead learn C++ from a proper book. After all, Timothy Williams claims that the above program outputs 322; it doesn't.
You cannot pass by reference a constant.
To break down your code.
int a(int m){
return ++m;
}
This will return an int (constant, eg. 5)
Then in
int b(int &m){
return ++m;
}
You are now technically passing in an integer (constant) not a variable into B. You must pass B in as a variable.
Try exactly what you have but passing in
int x = a(your_number_here);
int z = b(x);
EDIT:
int main(void){
int p=0,q=0;
int x = 5;
p = a(x);
q = b(p);
cout << q << endl;
return 0;
}
Returns 7.
The error is a result of trying to call a function that takes a reference with a value. It would be like calling b with a value literal b(1). That can't work...
The function call is where you pass by reference. See below:
void foo (int* m)
{
(*m)++;
}
int main (void)
{
int a = 0;
foo (&a);
cout << a << endl; // prints 1
}
So here b(int& m) takes a reference to an integer. Think about it this way. A reference is a "safe pointer" for which the compiler automatically handles the dereferencing operations.
The return value of a(int m) is a temporary, i.e. it is a temporary value that goes out of scope as soon as the function returns and its value has been utilized in some way. So you can do x = a(15); and x will become a copy of the returned 16. This is what an r-value is. A sort of "temporary" (r because it is on the right side of the expression). So when you have a pointer to a temporary value it does not make sense in most cases. For example in the following code
int* return_local() {
int a = 10;
return &a;
}
This will give you a compiler warning. Because you don't want to bind a pointer to a value which will go out of scope. Similarly you don't want a reference to an object that will go out of scope as soon as the function has returned and its value has been utilized. That is why there is an error in your code. a(int m) returns an r-value and when you do b(a(q) you are trying to bind a reference to an r-value
Now there is something called an r-value reference which takes the form void some_func(int&& rvalue_reference) in syntax. The && means r-value reference not reference to reference. Look it up if you are interested.
It's not allowed to pass a r-value as a non-const reference argument. This happens in the line whereyou call the function b with a(q) as its argument, which is an r-value (an expression which is not a simple variable).
So you need to first call a and store itsvalue in a variable, and then pass this variable to b:
int main(void)
{
int p=0,q=0,r=0;
p+=a(b(p));
int t=a(q);
q+=b(t);
r+=a(c(r));
cout<<p<<q<<r;
return 0;
}
This question already has answers here:
Modifying a const int in C++ [duplicate]
(2 answers)
Closed 7 years ago.
I have this piece of code:
#include <iostream>
using namespace std;
class X {
public:
const int x;
X(int i) : x(i) { }
int getX() const { return x; }
};
int main()
{
const X d(45);
const_cast<X *>(&d)->x = 47;
cout << d.getX() << endl;
const int j = 3; // j is declared const
int* pj = const_cast<int*>(&j);
*pj = 4;
cout << *pj << endl; //should not work, like above
return 0;
}
As I found here, Even though const_cast may remove constness or volatility from any pointer or reference, using the resulting pointer or reference to write to an object that was declared const or to access an object that was declared volatile invokes undefined behavior. They even proceed to provide examples below, the second one I gave, stating that it should give undefined behavior.
However, on compiling the code and running (here), the second one gives no error, and prints out 4 consistently. Whereas the first one throws error:
assignment of read-only member 'X::x'
const_cast<X *>(&d)->x = 47;
Of course, removing the const from declaration of x in X makes it work fine. However, it is also of the same type of mischief as the first one, changing a const thing through pointer after casting it const_ptr<>. But the first one works while the second one doesn't. Why so?
Both demands undefined behavior which unfortunately could mean working sometimes.
int* pj = const_cast<int*>(&j);
*pj = 4;
Also, Not all compilers are smart enough to figure out this kind of indirect manipulation.
Const-casting anything other than an actual const ptr* is probably a terrible idea, even if it does actually work most of the time.
That being said, the reason why your code doesn't compile properly is pretty straightforward: you remove the constness of the X object, but you fail to also remove the constness of the x member you're trying to modify.
Try this:
*const_cast<int*>(&(const_cast<X*>(&d)->x)) = 47;
This question already has answers here:
ampersand (&) at the end of variable etc
(5 answers)
Closed 3 years ago.
I am fairly new to programming. I am just moving on to C++ from C in my college courses, and I encountered something that I haven't seen before in C. Sometimes after the type, either in a function declaration or passing a parameter, a & immediately follows the type. For example, we use a struct called Customer in one of our projects, and some of the functions pass Customer&. Why is the ampersand after the type, as opposed to in front? Thanks!
References in C++ simply allow for a cleaner way to execute the following code:
int x = 16;
int* y = &x;
cout << *y;
Which could be written instead as
int x = 16;
int& y = x;
cout << y;
When defining functions, a reference allows a function to change the value of parameters without causing the user of the function to put an ampersand before everything. E.g.
void func( int& a )
{
a = 5;
}
void main()
{
int A = 10;
func( A );
cout << A; // Will output '5'
}
Be careful with this type of mutation, as a programmer using functions like this without checking the implementation might not realize that the function is changing the value of the parameters unless the intent is obvious. init_server(my_server) would be an example of a case where it's obvious, but to_json(my_struct) would clearly be an example where you should not be using a reference to change the struct in any way.
But, one of the most important uses of references, would be function like
int sum_vector( const vector<int>& a ) {
int sum = 0;
for( int i = 0; i < a.size(); i++ ) {
sum += a[i];
}
return sum;
}
If you tried to make sum_vector take in a vector, and you passed in a vector with 100 million entries, then it would have to copy them all over, taking forever. You could take in a pointer, but then the internal parts of the function would have to constantly dereference, and it must called with sum_vector(&myvec), which is more annoying than sum_vector(myvec). In this way, using a const reference, you can prevent the highly inefficient copying of the whole vector into the function body, while keeping syntax neat. Using const lets you reassure yourself that you're not going to change the vector that you were given. And, it also assures the user of your function that you won't change it. Similarly, void to_json(const some_struct&) would be a better function definition as it ensures you won't change the user's data.
This question already has answers here:
What does *& mean in a function parameter
(5 answers)
Closed 10 years ago.
I found this in a final exam:
int a = 564;
int* pa = &a;
int *& pr = pa;
cout << *pr;
According to the multiple choice answer, the code is valid, and displays the value of a.
But I'm confused about evaluation and precedence for line 3. Order of operations for C states that * and & have the same order. So, would it then be int *(&pr)? How can this be described in words?
Thank you.
The third line defines a pointer reference (or a reference to a pointer, if you want). Assigning it to a pointer makes pr to actually be an alias to pa, and when evaluated, it points where pa points to, that is, a.
In the declaration of a variable, * and & don't have the meaning of operators, so precedence doesn't make sense here.
It's a reference to a pointer. In C, you would express that as a pointer to a pointer.
You could write something like this:
// C++ style
void update_my_ptr(int*& ptr) { ptr = new int[1024]; }
// C style
void update_my_ptr_c(int **ptr) { *ptr = malloc(1024 * sizeof(int)); }
int main()
{
int *ptr;
update_my_ptr(ptr);
// Here ptr is allocated!
}
Line three creates a reference (read: alias) of a pointer to an int. If you were to set pr to 0, pa would also be equal to 0 (and vice-versa).