Statements in C++ - c++

In C++ want to write something like this
int Answer;
if (Answer == 1 || Answer == 8 || Answer == 10)
and so on, is it any way to make code shorter without repeating variable always?

Try:
switch (Answer) {
case 1: // fall through
case 8: // fall through
case 10:
// ... do something
break; // Only need if there are other case statements.
// Leaving to help in mainenance.
}

For readability I'd encapsulate the logic in descriptively-named functions. If, say, your answers are things with a particular color, and answers 1, 8, and 10 are green things, then you can write that logic as
bool ChoiceIsGreen(int answer)
{
return (answer == 1 || answer == 8 || answer == 10);
}
Then your function becomes
if (ChoiceIsGreen(Answer))
{
// offer some soylent green
}
If you have a lot of choices like this, I can see it getting hard to read if you have a lot of raw numbers all over the place.

If and only if you need to optimise for code size manually, and Answer is guaranteed to be positive and less than the number of bits in an int, you might use something like
if ( ( 1 << Answer ) & 0x502 )
But normally you don't want to obscure your logic like that.

You could put the values into a container and search the container.
Sounds like a std::set would be a wise choice:
if answer is in the set of (1, 8, 10) then do....
Remember that a std::set must be initialized during run-time, unlike numeric constants or an array of numeric constants. Before making any performance changes, first get the program working correctly, then profile if necessary, that is only if the program demands performance optimization.

Related

Can I use return to return to the start of an if statement?

I'm currently programming some homework, and we have to make a program that turns a hindu-arabic numeral into a roman numeral. I've already made the first part, where my teacher said we had to make sure the number is in between 1 and 3999. My algorithm so far is like this:
if (num-1000) > 0 {
add M to output
num -= 1000
return if
}
else {
(repeat for other digits, aka 500, 100, 50, and so on)
}
The problem is, I don't know if it's even possible. All the Stack Overflow pages I've seen say that I should use while statements for this, but since we haven't tackled while statements yet (even though I've self-learned it) we can't use while loops. So, can I use return to return to the start of an if statement?
What you are describing is a while. You can also achieve that with a go to but using that at this stage of learning would inspire some very very bad habits so I wholeheartedly discourage it. Another way you could do this is with recursion but that is an even more advance topic.
Given your restrictions (no loops, a number between 1 and 3999) I think you are supposed to use a bunch of ifs. Something like this pseudocode:
if (n >= 3000)
add 'M'
else if (n >= 2000)
add 'MM'
else if (n >= 1000)
add 'MMM'
n = n % 1000;
if (n >= 900)
add 'CM'
// and so on

Why is a switch not optimized the same way as chained if else in c/c++?

The following implementation of square produces a series of cmp/je statements like I would expect of a chained if statement:
int square(int num) {
if (num == 0){
return 0;
} else if (num == 1){
return 1;
} else if (num == 2){
return 4;
} else if (num == 3){
return 9;
} else if (num == 4){
return 16;
} else if (num == 5){
return 25;
} else if (num == 6){
return 36;
} else if (num == 7){
return 49;
} else {
return num * num;
}
}
And the following produces a data table for return:
int square_2(int num) {
switch (num){
case 0: return 0;
case 1: return 1;
case 2: return 4;
case 3: return 9;
case 4: return 16;
case 5: return 25;
case 6: return 36;
case 7: return 49;
default: return num * num;
}
}
Why is gcc unable to optimize the top one into the bottom one?
Dissassembly for reference: https://godbolt.org/z/UP_igi
EDIT: interestingly, MSVC generates a jump table instead of a data table for the switch case. And surprisingly, clang optimizes them to the same result.
The generated code for switch-case conventionally uses a jump table. In this case, the direct return through a look-up table seems to be an optimization making use of the fact that every case here involves a return. Though the standard makes no guarantees to that effect, I would be surprised if a compiler were to generate a series of compares instead of a jump-table for a conventional switch-case.
Now coming to if-else, it is the exact opposite. While switch-case executes in constant time, irrespective of the number of branches, if-else is optimized for a smaller number of branches. Here, you would expect the compiler to basically generate a series of comparisons in the order that you have written them.
So if I had used if-else because I expect most calls to square() to be for 0 or 1 and rarely for other values, then 'optimizing' this to a table-lookup could actually cause my code to run slower than I expect, defeating my purpose for using an if instead of a switch. So although it is debatable, I feel GCC is doing the right thing and clang is being overly aggressive in its optimization.
Someone had, in the comments, shared a link where clang does this optimization and generates lookup-table based code for if-else as well. Something notable happens when we reduce the number of cases to just two (and a default) with clang. It once again generates identical code for both if and switch, but this time,
switches over to compares and moves instead of the lookup-table approach, for both. This means that even the switch-favoring clang knows that the 'if' pattern is more optimal when the number of cases is small!
In summary, a sequence of compares for if-else and a jump-table for switch-case is the standard pattern that compilers tend to follow and developers tend to expect when they write code. However, for certain special cases, some compilers might choose to break this pattern where they feel it provides better optimization. Other compilers might just choose to stick to the pattern anyway, even if apparently sub-optimal, trusting the developer to know what he wants. Both are valid approaches with their own advantages and disadvantages.
One possible rationale is that if low values of num are more likely, for example always 0, the generated code for the first one might be faster. The generated code for switch takes equal time for all values.
Comparing the best cases, according to this table. See this answer for the explanation of the table.
If num == 0, for "if" you have xor, test, je (with jump), ret. Latency: 1 + 1 + jump. However, xor and test are independent so the actual execution speed would be faster than 1 + 1 cycles.
If num < 7, for "switch" you have mov, cmp, ja (without jump), mov, ret. Latency: 2 + 1 + no jump + 2.
A jump instruction that does not result to jump is faster than one that results to jump. However, the table does not define the latency for a jump, so it is not clear to me which one is better. It is possible that the last one is always better and GCC is simply not able to optimize it.

Nested if else, which one is it out of the options:

How is this called :
if else
if and if else
if or if else
if
none of the above
There is an if-else and an if :
if (n > 0) {
if ((n % 3) == 0) {
cout << "The number is positive and divisible by 3\n";
}
}
else {
cout << "The number is zero or negative \n";
}
//continue...
So looking at the possible answers, it's either the second one or the last one, depending if the order of the english text matters or not. The wording is unfortunate and ambiguous
Reasoning by elimination brings us to the same conclusions:
It definitively can't be just if nor if-else as there are 3 different branches with different outcomes.
It can't be if or if-else, because the two conditions in the diagramme are in cascade. This means clearly that the outcome depends of the two conditions (and), and not just one (or).
Edit: But if I'd have to answer in an exam, I'd say second answer because I see an if { and if } else : the ambguity of the english sentence gives me the right to understand that the else of the if and if else could be associated with the first if an not necessarily the second.
The graphic represents an if-else and an if. They do not appear in that particular order in the list of answers, so I would choose if and if else only if that answer is allowed to be ambiguous and the order is not important, otherwise I would choose none of the above instead.
If anyone needs to know this here it is :
IF AND IF ELSE
Why? Because when a new if statement comes after an if statement is true then it's called if and if else.
Otherwise if there was a new if statement on the left side where it's false it would be if or if else.
Thank you all.

Using of arithmetic and logical operators in switch statement [duplicate]

This question already has answers here:
Switch with range of values
(3 answers)
Closed 9 years ago.
I want to use logical operators in switch statment.
For Example:
" x is greater than 3 and is less than 7 "
Using it in If statement.
if(x > 3 && x < 7)
{
//something
}else if(x 11 3 && x < 15){
// anything
}
How can I use it in switch statement.
And how to use arithmetic operators.
UPDATE
Now how we use it in switch. Can there is not way to use it in switch.
You mean, something like this?
switch (some_var)
{ case 4 : // fall through
case 5 : // fall through
case 6 : do_something();
break;
default : do_something_else();
break;
}
It's ugly, and gets worse the larger a range you want to cover, but since switch cases must be constants, that's one way to do it.
Another way would be:
switch ((some_var > 3) && (some_var < 7))
{ case 0: do_something_else(); break;
default: do_something(); break;
}
But that'll only work if you have exactly one range you want to test. There are other ways if you have a set of equally-sized intervals that are spaced equally far apart, using some basic arithmetic, but we'd have to know a bit more about the specific problem(s) you're trying to solve...
Frankly, though, I think the if construct is the better solution...

c++ ignoring same number in an array

I have an array of random numbers, for example
6 5 4 4 8
I need to sort it and remove/ignore the same numbers while printing afterwards, so what I did is I sorted everything with bubble sorth algorithm and got something like this
4 4 5 6 8
Now in order to print only different numbers I wrote this for loop
for(int i=0;i<n;i++){
if(mrst[i]!=mrst[i-1] && mrst[i]>0){
outFile << mrst[i] << " ";
}
}
My question is, the array I have is at the interval of [0:12], though the first time when I call it, it checks an array index of -1 to see if there was the same number before, but it doesn't really exist, but the value stored in there usually is a huge one, so is there a possibility that there may be stored 4 and because of it, the first number won't be printed out. If so, how to prevent it, rewrite the code so it would be optimal?
Perhaps, you're looking for std::unique algorithm:
std::sort(mrst, mrst + n);
auto last = std::unique(mrst, mrst + n);
for(auto elem = mrst; elem != last; ++elem)
outFile << *elem << " ";
Well, as you noted already, you cannot do the check mrst[i] != mrst[i-1] in case i == 0. So I'm sure you can think of a way of not doing that check in exactly this case ... (This looks very much like a homework assignment, so I'm not really willing to give you a complete solution, but I guess I hinted enough)
Note also that it's undefined behaviour to access memory outside the boundaries of an array, so what you're doing there can do anything from working correctly to crashing your program, entirely at the discretion of the compiler.
Basically you can read from any place in heap. So mrst[-1] may give you some garbage from the memory. But you really should avoid doing this. In your case you can just change "mrst[i]!=mrst[i-1] && mrst[i]>0" to "i==0 || mrst[i]!=mrst[i-1]".
In c++ "A || B" don't execute "B" if the "A" is ok.