I have a code segment as follows:
if(a < b)
{
x = y;
return w;
}
/* all unrelated variables above*/
x = something;
y = something;
/*both x and y from above*/
x and y are global variables, and they are modified inside the if part, I need to assign y to x and then return w, or simply a constant.
I need to use a ternary operator to replace the if part:
I tried the following:
return (((a < b) ? (x = y, w) : 1), (x = something, y = something));
But, I don't seem to get the desired result. I know it is wrong. This is because I used the return stement from a similar expression, that is:
if(x < y)
return (x = y);
return 1;
Which I wrote as:
return ((x < y) ? x = y : 1);
But, how do I return a value, that involves a prior assignment of a completely different variable in a ternary operator?
The solution suggested by Mankarse:
return (a < b) ? (x = y, w) : (x = something, y = something, z);
Is actually equivalent to:
if (a < b) {
x = y;
return w;
}
/* all unrelated variables above*/
x = something;
y = something;
return z;
The second return statement is important.
You cannot conditionally return from the middle of an expression, because return is a statement, you have to return the whole expression. So it really depends on how you want to proceed after the assignment to the y. Or if you really need to change the order of execution in the middle of an expression, you can throw an exception, but that, I guess, would be too complicated in this case.
Put the code block inside a function.
function f(){
x = y;//assumes x, y and w are global.
return w;
}
Then use the function in the conditional statement.
(a < b) ? f() : "value to return if a>=b";
You don't need to put return before a conditional statement since automatically returns 1 of the value, depends on the evaluation of the condition.
Related
Why this code produce 1? Someone, describe it for me pls.
#include <iostream>
using namespace std;
int main(){
int x = 0;
int y = 0;
if (x++&&y++){
y += 2;
}
cout << x + y << endl;
return 0;
}
Initially x and y are 0
Therefore x++ evaluates to false, and the second operand of && is never evaluated. x++ does increment x to 1. Since the condition is false, the conditional branch is not entered.
x + y is 1 + 0 which equals 1
user2079303 explains nicely (+1 by me already), as extension, I'll go a little more into detail:
if(x++) evaluates the value of x before the incrementation, so this little piece of code is equivalent to the following (need to buffer the old value!):
int tmp = x;
x++;
if(tmp)
Be aware that within c && cc, the second condition cc is not evaluated any more if c is already false! So if(x && y) is equivalent to
if(x)
{
if(y)
{
// ...
}
}
Putting all this together, your code is equivalent to this variant, where I separated the if clause into code lines each one containing only one single instruction:
int x = 0;
int y = 0;
int tmp = x;
x++;
if(tmp)
{
tmp = y;
y++;
if(tmp)
y += 2;
}
Suppose, your output now is quite obvious...
I need a working MAX macros (without(!) declaring main function) which assign 'r' the maximum of numbers 'a' and 'b'. This code breaks in compilation. How can it be fixed?
#define MAX(x, y, r) ((x) > (y) ? (r = x) : (r = y))
int x = 10;
int y = 20;
int r;
MAX(x, y, r);
Thanks for watching!
UPD: Some revision to clear the full task:
#import <iostream>
#define MAX(x, y, r) ((x) > (y) ? (r = x) : (r = y))
int x = 1;
int y = 1;
int r = 1;
int main()
{
MAX(x++, y, r);
std::cout << r;
return 0;
}
The result of this code is 1, and need to be 2. So I need another logic in my macros to consider all postfix increments
You can't use this macro outside of a function, because it's an arbitrary expression, that's why you're getting an error.
Just move the invocation of the macro into function scope and it will work:
#define MAX(x, y, r) ((x) > (y) ? (r = x) : (r = y))
int x = 10;
int y = 20;
int r;
int main()
{
MAX(x, y, r);
}
Using macros in this case is, however, unnecessary (unless this is just an exercise to learn macro usage); making max a function (or, better yet, using std::max) would be a better and less error-prone way.
It doesn't work because you can't put arbitrary expressions at file-scope. I have a couple of suggestions:
Don't use global variables unless you really, really have to. They'll just cause you pain.
Don't use macros unless you really, really have to. They'll just cause you pain.
Here's what I'd do:
int main()
{
int x = 10;
int y = 20;
int r = std::max(x, y);
//pass x, y and r as arguments to functions rather than using globals
}
I want to find the maximum of the absolute of two variables, and return the actual value of that variable, rather than the absolute value of that variable.
For example:
int x = 3;
int y = -5;
int z = max(abs(x), abs(y))
Will just set z to 5, whereas I want it to return -5. Is there a C++ function to perform this?
If you're using C++11, with the STL you could use a vector of int, max_element and a lambda Compare
std::vector<int> values = {3, -5};
int largest_abs = *std::max_element(values.begin(), values.end(), [](const int& a, const int& b)
{
return abs(a) < abs(b);
});
This returns the iterator between the start and end of values, whose absolute value is the largest. (this is found through the comparator) The * is then used to convert the iterator (returned by std::max_element) to an int
It's not a commonly used function, but writing your own function is trivial.
int max_abs(int x, int y)
{
if (x == INT_MIN || y == INT_MIN)
return INT_MIN;
return (abs(x) > abs(y)) ? x : y;
}
int z = (max(abs(x), abs(y)) == abs(x)) ? x : y;
This is like an if-condition. Its equivalent to
int z = x;
if(max(abs(x), abs(y)) != abs(z))
z = y;
But much shorter.
There is no function in the STL to fit into your needs directly, so you need to make your own and this one could be one version.
A more handy one can be int z = (abs(y) < abs(x)) ? x : y thought.
I've been trying to get the arithmetic if operator to work but I just can't seem to do it.
I'm new to C++ and still learning the basics but I'm just wondering if I'm using this operator correctly. It's supposed to return false if x < y. Is this the correct way to do it? I'm aware I can use an if else but I'm just wondering if I can also do it like this and if I can what I'm doing wrong.
#include <iostream>
using namespace std;
int x =0;
int y =1;
bool test()
{
return (x < y) ? true : false;
}
int main()
{
cout << test;
return 0;
}
Change
cout << test;
to
cout << test();
Otherwise you're not calling the function.
Also, the following:
return (x < y) ? true : false;
does the opposite of what you say you're trying to do ("return false if x < y").
The correct way is:
return (x < y) ? false : true;
Note that in this case the ternary operator is unnecessary, since you can simply do:
return !(x < y);
You state:
It suppose to return false if x < y
And you're trying to learn about the arithmetic if (ternary) operator, so ignore all the advice to eliminate it.
The first part after the ? is what will be returned if the expression is true, and the second part after the : is what will be returned if it is not true. Thus you have your return values reversed, and it should be:
return (x < y) ? false : true;
Or even more simply,
return (x >= y);
I'm trying to make a function that takes in either 1 or 3 parameters, and returns either 1 or 3 values (based on parameters passed).
If 1 parameter is passed then the function uses default values for the other 2 arguments.
If 3 parameters are passed then it uses those values.
bool foo( bool x, int &y = 0, int &z = 0) {
x = true; y = y + 1; z = z + 2;
return x;
}
Is this possible in C++ or am I confused with Java functions.
You can do it with two functions:
bool foo( bool x, int &y, int &z) {
x = true; // this isn't really what it does, is it?
y = y + 1; z = z + 2;
return x;
}
bool foo(bool x)
{
int a = 0, b = 0;
return foo(x,a,b);
}
Any function always returns only 1 value. Returning 2 or more values is not possible directly.
Indirectly, it happens when you pass parameters by reference. Since the two parameters &y and &z are passed by references, hence changes to them can be reflected back directly.
You can do this by passing by reference..
by doing so you are making a method that points to a memory location.
When that memory location is changed, then your value is changed.
Link
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr233.htm
You cannot do that this way. You can, however, overload that function with different number of parameters, and return, maybe, a std::vector or std::list with the results.
EDIT:
Being more sophisticated, you can use tuples for that:
typedef boost::tuple<bool,int,int> my_data_t;
my_data_t my_tuple(true, 1, 0);
then, you define your function like this:
bool foo( my_data_t & t)
{
t.get<0>() = true;
int& y = t.get<1>();
y = y+1;
int& z = t.get<2>();
z = z+2;
return t.get<0>();
}
and call it this way:
bool result = foo ( my_tuple );
then, out of the function, you'll see my_tuple.get<1>() (the corresponding to y) as 2 (1+1).
I am not sure what you are trying to do, but you can kind of return multiple values of different type using boost::tuple.
boost::tuple<bool, int, int> foo( bool x, int y = 0, int z = 0) {
x = true; y = y + 1; z = z + 2;
return boost::make_tuple(x, y, z);
}
int main() {
boost::tuple<bool, int, int> result = foo(x, 1, 2);
std::cout << boost::get<0>(result) << boost::get<1>(result) << boost::get<2>(result);
}
You could also use boost::optional, if you only want to return x, if only 1 parameter is passed.
Btw. tuple is available in C++11 too.