c++ logical alternative operator - c++

During work over a simple project I have found situation that I don't fully understand. Consider following code:
#include <iostream>
using namespace std;
bool test(int k)
{
cout << "start " << k << endl;
bool result; // it is important that result's value is opposite to initial value of recheck in main()
result = false;
return result;
}
int main()
{
bool recheck;
recheck = true;
for (int i = 2; i > -1; i--)
{
recheck = (recheck || test(i)); // (1)
cout << i << " ???" <<endl;
}
cout << "----------------------------" << endl;
cout << endl;
recheck = true;
for (int i = 2; i > -1; i--)
{
recheck = (test(i) || recheck); //different order that in (1)
cout << i << "???" <<endl;
}
return 0;
}
It returns completely different results from for loops:
2 ???
1 ???
0 ???
----------------------------
start 2
2???
start 1
1???
start 0
0???
It seems that it first one test(int k) is not even invoked. I suspect it has something to do with || operator. Could anybody explain such a behavior?

The built-in || short-circuits: if the left operand is true, the right operand is not evaluated (it doesn't matter what the value of the right operand is, because the value of the || expression is guaranteed to be true in this case).
For completeness, but not particularly relevant to the question: In c++, the || operator is overloadable, just as many other operators are. If an overload is used, short circuiting does not take place.

The boolean operators || and && will short-circuit when one of the operands - evaluating from left-to-right - can determine the result of the expression, without reference to the remaining operands.
In the case of ||, this means that if the first operand is true, the remaining operands aren't evaluated, because the result of the entire expression will always be true.
In the first loop, the variable recheck - that is local to main - is always true, and so the function call test never needs to be evaluated: it is skipped, and you see no output.
In the second loop, the test function call is evaluated first, and it's result can only be determined after calling the function, so the function is called on each iteration, and you see the output.

Your comment says:
it is important that result's value is opposite to initial value of recheck in main()
Your test() function currently can't see the value of recheck, which is local to main().
Assuming your comment reflects your intent, you need to pass recheck as a parameter to test(); you can then use the unary ! operator, something like:
result = ! recheck;
And of course you need to fix the logic in main() so that test() is called when you need it to be.
Your requirements aren't clear enough for me to comment further.

Others have addressed the specific issue that you have raised. Just a note to say that beware of using multiple question marks in a row. Trigraph sequences start with two '??' characters and the third character after two question marks is interpreted differently.

Related

Why my static integer is not showing the changed value in the main function?

Here is my code. Here i is the static integer as global integer. As I know here the value of i should be 8 for n = 4. But it is showing 0. May be there is some lack of knowledge in me. Please let me know what I am missing.
#include<iostream>
using namespace std;
static int i;
int fib(int n){
i++;
if(n==0){
return 0;
}
else if(n==1){
return 1;
}
return fib(n-1)+fib(n-2);
}
int main(){
int n;
cin>>n;
cout<<"fib("<<n<<") = "<<fib(n)<<" calls = "<<i;
}
Here is my output:
fib(4) = 3 calls = 0
Your static integer has nothing to do with it. The problem is due to use of operator<<, order of evaluation and operator precedence / sequence points. The reason is that i gets evaluated first which at this point is equal to 0 and gets sent to output stream. Then the fib(n) function gets evaluated and sent to output stream. Break the expression into two statements instead:
std::cout << "fib(" << n << ") = " << fib(n);
std::cout << " calls = " << i;
This will ensure the the proper order of evaluation where fib(n) gets evaluated first and i gets evaluated second.
The problem here is that in a statement like
cout<<"fib("<<n<<") = "<<fib(n)<<" calls = "<<i;
the output will be in the order you write it, but there is no guarantee for what order the computation of each expression will happen. In your example i is being calculated first, then fib(n).
Try this instead
int main(){
int n;
cin>>n;
int tmp = fib(n);
cout<<"fib("<<n<<") = "<< tmp <<" calls = "<<i;
}
The value i is being read by << before fib(n) is called?
Never "do work" in a diagnostic.
Also you didn't initialise i to 0.
This happens because your compiler is outdated.
As other answers explain, the compiler chooses to read i's value before calling fib(n). However, what they fail to tell is that the current C++ standard requires i's value to be read after calling fib(n). The program is already supposed to do exactly what you expect it to do.
According to C++ compiler support - cppreference, the new evaluation rules have been implemented in GCC 7 and in Clang 4. You may either modify your code to be acceptable to older compilers, or switch to a more up-to-date compiler.
This is a C++17 feature, though, and the default is not to compile in C++17 mode. You might need to add -std=c++17 or similar to your command-line options.

Functions not executing in order provided [duplicate]

This question already has answers here:
function parameter evaluation order
(5 answers)
Closed 8 years ago.
I have this problem with my functions.
in the main function I have this result(param, param) function which takes 2 functions as parameters.
result(name(), score());
However when the code executes the score() function executes first and not the name() function. why does that happen.
(Also another problem that arises from the score() function executing first and not the name() function is that I get the \n read and the name() function is skipped altogether. However I know how to fix that I just need to know why isn't the name() function executed first. ).
I found this here: http://en.cppreference.com/w/cpp/language/eval_order.
Order of evaluation of the operands of any C++ operator, including the order of evaluation of function arguments in a function-call expression, and the order of evaluation of the subexpressions within any expression is unspecified (except where noted below). The compiler will evaluate them in any order, and may choose another order when the same expression is evaluated again.
There is no concept of left-to-right or right-to-left evaluation in C++, which is not to be confused with left-to-right and right-to-left associativity of operators: the expression f1() + f2() + f3() is parsed as (f1() + f2()) + f3() due to left-to-right associativity of operator+, but the function call to f3 may be evaluated first, last, or between f1() or f2() at run time.**
But my program always executes the score() function first. And above it states that it is random so I should at least have the name() function executed first sometimes right?
Full code is here for reference.
#include <iostream>
#include <string>
using namespace std;
string name()
{
string fname;
cout << "Please type your full name: ";
getline(cin, fname);
return fname;
}
int score()
{
int points;
cout << "Please type your score: ";
cin >> points;
return points;
}
void result(string fname, int points)
{
cout << "Ok " << fname << ", your score of " << points << " is ";
if (points > 100)
{
cout << "Impossible";
}
else if (points == 100)
{
cout << "Perfect!!!";
}
else if (points >= 85 && points < 100)
{
cout << "Amazing!!";
}
else if (points >= 70 && points < 85)
{
cout << "Good!";
}
else if (points >= 50 && points < 70)
{
cout << "Ok.";
}
else if (points < 50)
{
cout << "Bad...";
}
else
{
cout << "Incorrect input";
}
}
int main()
{
result(name(), score());
return 0;
}
In this line:
result(name(), score());
the order of evaluation for the function arguments is not defined. It just so happens that this is the order of evaluation with your particular compiler (and compiler flags). If you want the functions to be executed in a particular order then you'll ned to call them in the required order first:
string s = name();
int t = score();
result(s, t);
It's not random, it's unspecified.
Which means that the compiler is free to do what it wants.
Here the compiler decided that it's best to always call score() before name(), and will not change its mind without a good reason.
Maybe another compiler would have decided something else, maybe it depends on the phase of the moon, you can't tell and you're not supposed to try to guess what's going to happen.
Unspecified means that you can't expect it to behave in any particular way, you can't rely on it.

Logical operations in cout [duplicate]

This question already has an answer here:
The output of cout << 1 && 0;
(1 answer)
Closed 7 months ago.
Consider:
int i = 56, j = 0;
int n = i&&j;
cout << i&&j;
cout << endl << n;
whose output would be:
56
0
I imagine it's either because of operator precedence or logical short circuit, but I can't seem to figure out which, or the reason.
The expression cout << i&&j is equivalent to (cout << i) && j. Both operands are evaluated and converted to bool. The statement as a whole has no effect, but the evaluation of the subexpression cout << i has the usual side effects, of course, namely writing something to the standard output.
The && operator is indeed short-circuited and j is only evaluated if cout << i evaluates as true. This condition is equivalent to cout.good(), which is usually the case (unless you somehow managed to close your standard output).
As you expected, the << operator comes takes precedence over &&.
Thus, cout << i&&j first outputs i, then compares the returned stream to j (both are true, so the returned value is true, but this value is discarded).
See here for the full list of operator precedence.

Can you explain HOW bool can control loops?

I'm a beginner programmer in C++ (currently), and I've got a conceptual question.
I'm trying to filter a cin input to ensure that it is a one-or-two-digit integer between 01-04, and if it isn't, to produce an error and ask for a new input.
I'm also using map to give the user a list of options that, upon valid selection, routes inputs (integers) through any of several methods to produce a relevant result, but I'll ask a more specific version of this question elsewhere.
I found a snippet of code at http://www.cplusplus.com/forum/beginner/26821/ that is meant to validate an input. I sort of get it, except where the boolean condition is set inside the while loop. Because I don't understand it, it makes it very difficult to edit or make sure that I'm manipulating it right.
Here is the example code:
int main()
{
int num;
bool valid = false;
while (!valid)
{
valid = true; //Assume the cin will be an integer.
cout << "Enter an integer value: " << endl;
cin >> num;
if(cin.fail()) //cin.fail() checks to see if the value in the cin
//stream is the correct type, if not it returns true,
//false otherwise.
{
cin.clear(); //This corrects the stream.
cin.ignore(); //This skips the left over stream data.
cout << "Please enter an Integer only." << endl;
valid = false; //The cin was not an integer so try again.
}
}
cout << "You entered: " << num << endl;
system("PAUSE");
return 0;
And here is my code (the entire thing, to give context). I don't think it's complete, I just want to make sure I'm using the boolean right.
float _tmain(float argc, _TCHAR* argv[])
{
bool validInput = !true;
map<string,int> Operations;
Operations.insert(pair<string, int>("Addition", 01));
Operations.insert(pair<string, int>("Subtraction", 02));
Operations.insert(pair<string, int>("Multiplication", 03));
Operations.insert(pair<string, int>("Division", 04));
cout << "Welcome to OneOpCalc, what operation would you like to perform?" << endl;
for(map<string, int>::iterator ii=Operations.begin(); ii!=Operations.end(); ++ii)
{
cout << (*ii).second << ": " << (*ii).first << endl;
}
while (!validInput)
{
cin >> operatorSelection;
if (cin.fail() || operatorSelection < 4 || operatorSelection > 1)
{
cout << "Error: Invalid selection. Please choose a valid number." << endl << endl;
cin.clear();
cin.ignore();
}
}
}
Does while (!valid) mean "While valid is false"? In my head, it's saying "While valid is !valid", which obviously, would always be false.
EDIT: Thanks for the answers guys, I'm looking through them all. One answer I keep getting goes too general; I understand that ! is NOT, and I understand the concept of flipping the bool using it. However the implicit logical implications are what confuse me. In any given statement, I am used to thinking of !valid as a way of flipping the valid value; Not testing a condition. It's the syntax of using it to test a condition that tricks me. In other words, writing while(!valid) reads literally to me as while(NOTvalid), not while(valid==false). I can't get myself to understand why in this case, !valid reads as a condition and not just a bit-flip.
Loops (and ifs) are controled by an expression of type bool.
In while ( !valid ), the expression is !valid, the operator
not applied to the value of the variable valid.
while ( !valid ) means (literally) while the expression
!valid (which means "not valid") is true.
For the rest, the code you're copying is pretty bad. I wouldn't
use it as an example if I were you.
As for your own code:
_tmain is very particular to Microsoft. You don't want to
use it. If your writing a console application, just use main.
(Same thing holds for _TCHAR, rather than char.)
Neither _tmain nor main can return a float. The return
type of main should always be int. I'm less familiar with
_tmain, but it's either int or void. (Probably int, if
you're in a console mode program.)
!true is false. Always. (Programming is different than
the real world. There are no maybes.) Why be more
complicated than necessary?
There's no need for the flag variable at all. You
can just write:
cin >> operatorSelection;
while ( !cin || operatorSelection > 4 || operatorSelection < 1 ) {
// ...
}
In case of error, you currently only ignore a single
character. You probably want to ignore up to and including the
end of line.
(std::cin.ignore( std::numeric_limits<std::streamsize>::max() );.
And the condition in your if will always be true. (See my
version above.) Where do you expect to find a number which is
neither less than for nor greater than one?
In your code, inside the loop, just add:
else
validInput = true;
after the if closing bracket.
You want to get out of it once the user has typed a correct value.
You want to run the loop "while there is not a valid input". Remove the non-bold words, and translate to C++.
Of course, the second case is not working, because nothing changes validInput inside the loop, so it stays "invalid", and the loop continues forever (And if you want to set something to false then bool validInput = !true; is more convoluted than bool validInput = false; - the compiler will do the same thing, but someone reading the code will have to think to see what it does - it is a good thing to think when reading code, but it's not a good thing to write code that is more complicated than necessary...).
A while loop has a condition and a body, the body is executed as long as the condition evaluates to true.
From the C++ standard:
6.5.1 The while statement
In the while statement the substatement is executed repeatedly until the value of the condition (6.4) becomes
false. The test takes place before each execution of the substatement.
A while loop can have one of the following forms
while ( condition ) statement
while ( condition )
{
statement(s)
}
The ! operator is a logical not and this is how you should read it: while not valid. You could have also written that as:
while(valid == false)
or
while(valid != true)
Note that here, again, != is equivalent to not equal.
nijansen forgot to add the most elegant one
while(!valid)
which is the same as the 2 others

Are these two while loops equivalent?

I have two snippets:
while (indent-- > 0)
{
out << " ";
}
while (indent > 0)
{
indent -= 1;
out << " ";
}
As far as I can see, there isn't any undefined behaviour going on in the first snippet (see here).
My question is: are these two snippets equivalent?
I am not so sure, because the -= operator has a higher precedence than the compare operator, and should therefore be performed first in the first snippet. The second snippet however, only performs this after comparison.
They will run the body of the loop the same number of times, but they are not the same.
The first will decrement indent one extra time, leaving indent at -1, because the -- operator will run whether the condition succeeds or fails.
The second will leave indent at 0. Here's a complete working example:
#include <iostream>
int main()
{
int indent = 3;
while (indent-- > 0)
{
std::cout << "First "; // Prints three times
}
std::cout << indent << std::endl; // Prints -1
indent = 3;
while (indent > 0)
{
indent -= 1;
std::cout << "Second "; // Prints three times
}
std::cout << indent << std::endl; // Prints 0
}
// Output:
// First First First -1
// Second Second Second 0
There's no difference between the two because indent-- is a post-increment - it will return the previous value of indent - there would be a difference for while (--indent > 0) though.
So, for basic types, they're equivalent.
Since this is C++, though, you can just as well define your own class, have indent an object of that type, overload -- and =(int) and > and have them behave completely different (I hope this isn't the case).
EDIT: correct, the value of indent isn't the same.
I think they are different. What is missing is initialization of indent and its type.
First loop will always decrement after comparison, second only when condition was true. If (indent > 0) is true before loop, they behave exactly the same way. If indent==0 however, first loop will make it -1 without printing it once. Second will not print any indent, but wont decrease indent also.
So, they are different in some cases.