This is an example problem to demonstrate the use of references in c++. i'm a beginner and this is my first time learning about references. i don't understand why we use &fun(). what does it mean?
#include<iostream>
using namespace std;
int &fun(){
static int x = 10;
return x;
}
int main(){
int &y=fun();
y = 20;
cout<<fun();
}
output : 20
Equivalent syntax is int& fun().
So this function returns a reference to 'x' (that is static), so later in main you can modify it (y = 20 does change the x inside the function).
So another invocation returns 20, as the x had been changed.
int & means fun() is returning a reference to an int. In main(), that reference is assigned to y, and the value of y is modified to 20, also changing the value of x to 20.
Related
#include <iostream>
using namespace std;
int division(int c, int d);
int x = 2;
int y = 2;
int division(int c, int d)
{
return (c/d);
}
int main()
{
cout << "Hello World!\n";
int x = division(x,y);
cout << x;
return 0;
}
I expected the code to show 1 after Hello World!, but it prints 0.
I removed int from in front of x (in main()) and ran it again and it returned 1.
But I also passed x,x to the division function with the int in front of x (in main()) and it returned 1.
So I am not sure how the assignment statement is working.
This expression:
int x = division(x,y);
is equivalent to writing this:
// 'x' was defined globally somewhere here before
int x;
x = division(x, y);
This shadows the previous x variable defined globally and defines a local variable x which again is uninitialized so after passing it in the division() function, your code has Undefined Behavior. (When that happens, the output can be anything, it can be 0, it can even be 1 or something else entirely.)
What you want to do is to remove the declaration and turn it into an assignment instead:
x = division(x,y);
Then the above works properly and gives 1.
You should compile your code at least with -Wall flag.
You would then see a helpful warning message:
foo.cpp: In function ‘int main()’:
foo.cpp:17:21: warning: ‘x’ is used uninitialized [-Wuninitialized]
17 | int x = division(x,y);
| ~~~~~~~~^~~~~
It means that to the division() isn't passed global x, but the local one from main().
It's undefinied behaviour, no different than int z = division(z,y);
After removing int from before x in main() you no longer declare local variable, thus there is only one x in your program (the global one) and from initialization the line turns into plain assignment.
the output of the code is 30.But I am not sure how it is getting to it.
#include <iostream>
int &fun()
{
static int x = 10;
return x;
}
int main()
{
fun() = 30;
std::cout << fun();
return 0;
}
I am expecting that the output will be 10 but its showing 30. how?
Your fun gives a location of an int (since it returns a reference). That location is the static variable x which is initialized (once, conceptually before the program runs) to 10.
Then fun() = 30; is assigning that location. So x gets assigned to 30.
At last cout << fun() displays the content of that location.
If x was some automatic variable your code would have undefined behavior.
PS. A crude way of thinking about & unary reference like int &r = x; is that it sort-of "transforms" your code as: introduce a phantom pointer int *p = &x; (where p is some fresh variable not appearing elsewhere) and replace r with *p, so &r with p, everywhere in the scope of that r.
Can we have a function calling at the left side of the expression?
This code snippet works well but how? How can a function calling can be at left side and please elaborate how this snippet is executing and working well and what if i wouldn't have used static int in function definition.Thanks in advance.
#include<iostream>
using namespace std;
int &fun()
{
static int x;
return x;
}
int main()
{
fun() = 10;
/* this line prints 10 on screen */
printf(" %d ", fun());
getchar();
return 0;
}
Any expression that returns a non-const lvalue can be on the left side of the assignment and function call is also an expression like any other. Since lvalue historically means exactly that - value on the left side this turns into a recursive definition. So instead you can consider an lvalue anything that you can take address of:
int x = 5;
&x; //valid, takes the address of the variable
&5; //invalid, integer literal has no address
int func1();
&func1(); //invalid, can't take the address of the temporary value
int &func2();
&func2(); //valid, since the function returned reference
//which itself is almost the same as the address
So any expression that results in something addressable can be assigned to. You can even do something like this:
int x = 0;
int y = 0;
int z = 5;
(z > 5 ? x : y) = 10;
As for your second question, if you remove static from your function you would return a reference to a local variable of the function. Local variables stop existing when the function exits, so you would return a reference to a variable that is already destroyed. This, however, will compile and run, but the results of that execution would be unpredictable that's why this is called undefined behavior.
I do not understand why mysteryfunction(y) will equate to 40
when i int mysteryFunction(int, int =2). Anyone can explain to me?
Best, MM
#include <iostream>
using namespace std;
int mysteryFunction (int, int = 2);
int main()
{
int x = 10, y = 20;
cout << mysteryFunction (y);
}
int mysteryFunction (int x, int y)
{
return x * y;
}
In the declaration ofmysteryFunction() the second parameter is assigned a default value of 2, so if you call it only with one argument the second argument y will be 2.
Hence doing mysteryFunction(20) is basically the same as doing mysteryFunction(20, 2), which according to your code should return 20 * 2 = 40.
You may have been confused by the fact that the variable you pass to mysteryFunction() as its first argument is named y, same as the second parameter in its definition. However, those are completely different variables. In fact, it doesn't matter how you call them, only the position of arguments/parameters matters (along with their type if you take function overloading into account).
They will assume by default that y will be 2, thus when you fill in int x, it'll automatically take in (x,2).
In your declaration for mysteryFunction you give a default value of 2 to the second argument. Then you call it with only 1 argument so the default gets used for the second argument. So y=20 and 20 * 2 = 40. Don't mix up variable names. The x and y in main have nothing to do with x and y in mysteryFunction
Take the following code, where a function returns by reference:
#include <cstdio>
using namespace std;
int & myFunction(int & input) {
return input;
}
int main() {
int x;
int y = 10;
x = myFunction(y);
printf("x is %d\n",x); // x is 10
printf("y is %d\n",y); // y is 10
x = 20;
printf("x is %d\n",x); // x is 20
printf("y is %d\n",y); // y is 10
return 0;
}
Except the obvious pitfall of returning a reference to a local variable of the function (which is not the case here), are there any things to watch out for in this kind of setup? In other words, is there anything "more" to this code than a function which simply returns things by reference in order to avoid unnecessary copying operations?
Except the obvious pitfall of returning a reference to a local
variable of the function (which is not the case here), are there any
things to watch out for in this kind of setup?
No, not really, it's perfectly valid but it has no advantage either. (in the current state of myFunction)
in order to avoid unnecessary copying operations?
There's still a copy being made here:
int x;
int y = 10;
x = myFunction(y); // value of y is copied to x.
This is less readable and doesn't speed up anything when it comes to just normal initialization:
int x;
int y = 10;
x = y;
There's no reason to do this in this situation, just stick to normal initialization.
Of course, if myFunction adds some kind of modification to a more complex object than int& then you can take advantage of returning the reference as you can then:
chain.method().calls();
The code you provided works because you're passing the variable to your function by reference, and still returning it by reference. This is consistent and works, but is weird. Why would you return the same variable that you're passing by reference? (I just remembered from the comments that this is useful for chaining in std::ostream, for example.)
On the other hand, if you pass that variable by value, you'll have a dangling reference and it won't work. So this won't work:
int & myFunction(int input) {
return input;
}
In my opinion, the only return by reference I find appropriate is if you return a variable from inside a class's method. Besides that, I don't think you should return by reference at all.
You can catch a variable as a constant reference and avoid copying it if you want without having a dangling if you do this:
int myFunction(int input) {
return input;
}
int main()
{
const int& myInt = myFunction();
//myInt is still valid here
}
This is a special case that.