Why won't my values swap? - c++

I am supposed to write a function name double_swap that takes two doubles as arguments and interchanges the values that are stored in those arguments. The function should return no value, so I know that means it must be a void function.
For example, if the following code fragment is executed,
int main()
{
double x = 4.8, y = 0.7;
double_swap(x,y);
cout<<"x = "<<x<<" y = "<<y;
}
The output will be:
x = 0.7 y = 4.8
The program I wrote is not swapping the values. I'd greatly appreciate if someone could point out my errors.
#include <iostream>
using namespace std;
void double_swap(double x, double y)
{
x = 1.9;
y = 4.2;
}
int main()
{
double x = 4.2, y = 1.9;
double_swap(x,y);
cout<<"x = "<<x<<" y = "<<y<<endl;
return 0;
}

You need to pass the variables by reference in order for the modifications in the function to apply to the variables from the call site. As it is right now all you are doing is modifying copies that get destroyed once the function ends.
Change
void double_swap(double x, double y)
to
void double_swap(double& x, double& y)
Also instead of hard coding the values lets do a real swap using
void double_swap(double& x, double& y)
{
double temp = x;
x = y;
y = temp;
}
You could also use pointers for the function paramters for this but then your call site would have to be changed to double_swap(&x,&y); and you would have to remember to reference the pointers in the function.
Instead of doing all of this though we can just use std::swap and let it do this for us.

When calling a function in c++ , There is 3 way to pass the parameters. The first one is by Copy where it only make a copy of the variable in parameters and then delete them.
void double_swap(double x, double y)
The second one is by Reference, where the paramaters refere to the real variable (Whats you want).
void double_swap(double& x, double& y)
And the last one is by address where you pass the address of the variables.
void double_swap(double* x, double* y)

Related

Does a const variable behave like a static variable when defined in a C++ function?

I have a small query. In C++, is it legal and/or sensible to define a const integer within a function, the value of which depends on the input arguments of the function? And if it is, does the value stay constant within the function and changes with different calls to the function with different arguments, or does it stay constant over the scope of the entire program like a static variable?
Here's a quick example of what i mean in code.
void testMyVar(int x, int y){
const int z = x/y;
//use z for whatever computation
}
Thanks for your help in advance!
A variable declared as const cannot be modified once it is initialized.
In this case, when the function is entered z is initialized with the value of x/y and will keep that value for the duration of the function. And each time the function is called, z will be initialized with whatever values for x and y were passed.
There is no behavior related to static since the variable was not declared static.
Realize that z is "destroyed" once it goes out of scope since it is NOT static. This is true if z is at function scope or nested 3 levels deep in an if/for/if
static int z = 42; // I will label this z0
void testMyVar(int x, int y) {
const int z = x/y; // I will label this z1; this z is different than the static z above (z0)
if (z > 10) { // tests z1, not z0
int z = x; // non-const z; I will label this z2, which is different than z1 and z0
z++; // C++ uses inner-most scoped z (so here, it's z2), so this is good (non-const)
for (int i = 0; i < z; i++) {
int z = i / 2; // I will label this z3, it gets re-evaluated every time through the for loop
z = z * z; // all 3 z refererences here is z3
cout << z << endl; // dumps z3
cout << ::z << endl; // dumps z0 note the global scoping operator ::
} // z3 gets "destroyed"
} // z2 gets "destroyed"
} // z1 gets "destroyed
C++ grammar does not provide mechanisms for specifying scope of named variables at different code scopes, just at global, class/struct, and namespaces. So you cannot specifically utilize the top level const int z (what I labeled z1) within the code nesting levels where deeper z's z2/z3 are defined. Note that I CAN reference the "global" scoped static z ::z at the z3 level by utilizing the global scope operator ::

The & should follow type or in front of the parameter when using reference as function parameter?

from what I know, if we use pointer or reference as a function parameter, it could written like this:
for reference:
void myfunction(int& x);
for pointer:
void myfunction(int *x);
but I recently see people written like this:
void myfunction(int &x);
I think it is still a reference, but if in general &x means getting the address of x, right? So, I am confused. Please help.
Edit: please also help with the below code, not sure if the unexcepted result is causing by the way how I use reference:
what I want to achieve is using myrecursive to return the value if the size of control_point is 1, and using this value from another function
cv::Point2f myrecursive(const std::vector<cv::Point2f> &control_points, float t)
{
if(control_points.size() != 1)
{
std::vector<cv::Point2f> temp_points;
for (int i = 0; i < control_points.size() - 1; i++)
{
cv::Point2f t_point;
//some code
temp_points.push_back(t_point);
}
myrecursive(temp_points, t);
}
return control_points[0];
}
void myfunction(const std::vector<Point2f> &control_points, cv::Mat &window)
{
for (double t - 0.0; t <= 1.0; t +=0.1)
{
cv::Point2f point = myrecursive(control_points, t);
}
}
but if I print point in myfunction, it is always the first value of the original control_points
for example: the original control_points is ([0,1], [2,3]), after operation in myrecursive, assume it should return a point [5,6]. But in this line
cv::Point2f point = myrecursive(control_points, t); it alway return [0,1], why this happen?
but if in general &x means getting the address of x, right?
Outside a declaration, the & operator is the "address-of" operator. However, when declaring a variable, & is not an operator, but has a completely different meaning. It means that the declared variable is a reference.
The compiler doesn't care whether you write int &x or int& x. In both cases, it has the same meaning. Therefore, it is a matter of personal preference.
Personally, I prefer to write int &x, because writing int& x can be misleading, for example in the following situation:
int& x, y;
This formatting implies that both x and y are references, i.e. that the & refers to both x and y. However, according to the C++ syntax rules, the & only refers to x. Therefore, using this formatting style can lead to errors.
However, if you instead write
int &x, y;
then it is clear that the & only refers to x and not y, and it is immediately apparent that you must add a & if you want y to also be a reference.
On the other hand, when declaring only a single variable, writing int& x may be better, as it separates the name and the type of the variable.

What kind of design pattern to access encapsulating scope variables in a lambda function without changing the signature?

I am using a library for an optimizer (Brent's method) that has a function "local_min".
Its prototype is defined roughly as follows:
double local_min ( double f ( double x ) );
The function accepts a function pointer (?) as a parameter. Suppose f(x) is the function... the optimizer will test various values for x to find a minimum value for f(x).
The local_min function is called such as:
double f(double x){
return .5 + x * x;
}
int main(){
double fx = local_min(f);
return 0;
}
The trouble I am having is that I want to define the .5 as a scalar for the function, but I do not want to use global values. Ideally, I would have everything in a single class. But everything I try, I change the function signature of f(x) and it will no longer be accepted by local_min().
For example:
int main(){
double value = 0.5;
auto lambda = [](double x) {
return value + x * x;
};
double fx = local_min(f);
return 0;
}
does not work because value is not accessible. Similarly,
int main(){
double value = 0.5;
auto lambda = [&](double x) {
return value + x * x;
};
double fx = local_min(f);
return 0;
}
changes the function signature and is no longer accepted by local_min().
Instead of a function pointer, make local_min accept an arbitrary type. This will let you pass it a lambda with captures as desired
template<typename F>
double local_min(F f)
{
// ... same usage as before
}
The callable f will still behave the same way as before, i.e. like a function that takes a double and returns a double. If you call local_min with an incompatible type, it will fail to compile. You can check for this with a static_assert to give the user a nice error message if you want.

Change given function parameter within the function c++

I wrote an function called swap to swap given two elements within the function. But when I use it in another function, it doesn't work. How to get it work?
#include <iostream>
using namespace std;
void swap(int *a, int * b){
int temp=*a;
*a=*b;
*b=temp;
}
void sum(int x, int y){
int *a;
a = &x;
int *b;
b=&x;
swap(a,b);
//cout << x << endl << y << endl;
}
int main(){
int a=0, b=1;
//swap(a,b);
sum(a,b);
cout << a << endl << b << endl;
return 0;
}
b=&x;
should be
b=&y;
Also, you are swapping local copies. sum should be:
void sum(int& x, int& y)
Also, this already exists. It's called std::iter_swap.
You probem not in swap, but in sum function, you pass x an y by value and modify and swap copyies of values later to fix this you need to change void sum(int x, int y){ to void sum(int& x, int& y){ this will leads to x and y being passed by reference so that sum will be able to update them.
I guess by 'wrong' you mean the output of the last cout doesn't show 'a' and 'b' as you'd expect. But you're passing them to 'sum' by value.
I assume you are just learning about pointers and references.
Your function swap swaps the contents of two pointers. Note that you have put in using namespace std and std also has a swap function so I would suggest removing that from your source, albeit yours will be a closer match if you pass in pointers to ints.
Your function called sum is a clear misnomer as it doesn't actually sum or add anything, it tries to do a swap by calling the pointer version.
To fix your particular bug, it would have to take its parametesr by reference, and b should point to y, not x.
x and y are passed by value to sum so swap is working on a local copy not the actual variables from main. You will also need to modify sum and your call to swap:
void sum(int &x, int &y)
^ ^
{
// other code
swap(&x,&y);
^ ^
}
If you leave you call to swap like this:
swap(x,y);
you will actually call std::swap. I am going to assume you will be adding more code to sum otherwise the name is not consistent with what it does.

Can 'return' return multiple values in C? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
C++ — return x,y; What is the point?
Here's a piece of code that executes perfectly in C.
int a=3,b=4,x,y;
x=a+b;
y=a*b;
return(x,y);
This function returns 12. Can someone please explain.
This is because you (inadvertently) use the comma operator, whose value is that of the last expression included. You can list as many expressions as you like, separated by the comma operator, the result is always that of the last expression. This is not related to return; your code can be rewritten like
int tmp = (x, y); // x = 7, y = 12 -> tmp is assigned 12
return tmp;
[Updated] You don't usually need brackets around the list, but here you do, due to the assignment operator having a higher precedence than comma - kudos to #Draco for pointing it out.
Edit : This answers the title Q, viz 'can return return multiple values'
Not exactly. You can
return the second variable by using reference (or pointer) parameter
otherwise, create a new class or struct containing x and y and return an instance of this new class
No, you cannot return multiple values simply by using (x, y) — this is not a tuple, as you might expect from other languages, but a bracketed use of the comma operator, which will simply evaluate to y (which will, in turn, be returned by the return).
If you want to return multiple values, you should create a struct, like so:
#include <stdio.h>
struct coordinate
{
int x;
int y;
};
struct coordinate myfunc(int a, int b)
{
struct coordinate retval = { a + b , a * b };
return retval;
}
int main(void)
{
struct coordinate coord = myfunc(3, 4);
printf("X: %d\n", coord.x);
printf("Y: %d\n", coord.y);
}
This shows the full syntax of using a struct, but you can use typedef if you prefer something like:
typedef struct
{
int x;
int y;
} coordinate;
coordinate myfunc(int a, int b)
{
coordinate retval = { a + b , a * b };
return retval;
}
// ...etc...
The answer to your question is "no, return cannot return multiple values". Here you see the result of the evaluation of the legal expression x,y, which is y i.e. 3*4 = 12.
The comma operator is just a binary operator. The right-most value is returned.
That's the comma operator. It evaluates its left side, then evaluates its right side, and its resulting value is the right side.
So, return(x,y) is the same as return y, since evaluating x has no side-effects.
The only way to "return multiple values" in C is to return a struct by value:
#include <stdio.h>
typedef struct {
int sum;
int product;
} sumprod;
sumprod get_sum_and_product(int x, int y) {
sumprod ret = {x + y, x * y};
return ret;
}
int main() {
sumprod values = get_sum_and_product(3,4);
printf("sum is %d, product is %d\n", values.sum, values.product);
}