'Testing the same condition without OR operator
My lecturer does not want us to use the OR operator when using an if statement neither should both condition testing be on the same line. eg.
if(condition1 || condition2){
statement
}
if(condition1 || condition3){
statement
}
But we've received a project asking for us to update books where the user can select either options, or both options. I tried using a switch, but I think its too long.
A sample of the code is below. However, is there any way to shorten it without using the case 3 and typing redundant code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int opt;
printf("(1) Option 1");
printf("\n(2) Option 2");
printf("\n(3) Both\n");
printf("Choice: ");
scanf(" %d", &opt);
switch(opt){
case 1:
printf("\nThis is option one");
break;
case 2:
printf("\nThis is option two");
break;
case 3:
printf("\nThis is option one");
printf("\nThis is option two");
break;
}
return 0;
}
Solution 1:[1]
You can use De Morgan's laws to avoid the OR. The relevant one
not (A or B) = not A and not B
which when transformed to your case becomes
A or B = not (not A and not B)
Here is the truth table to showcase this logic
| A | B | A or B | not A | not B | not A and not B | not(not A and not B) |
|---|---|---|---|---|---|---|
| true | true | true | false | false | false | true |
| true | false | true | false | true | false | true |
| false | true | true | true | false | false | true |
| false | false | false | true | true | true | false |
So with this in mind the condition
if(condition1 || condition2)
turns into
if (! (!condition1 && !condition2) )
Solution 2:[2]
In this case you can use the bitwise AND-operator (&) instead:
if(opt & 1)
{
// option 1 or 3 chosen
}
if(opt & 2)
{
// option 2 or 3 chosen
}
The decimal numbers 1, 2 and 3 are in binary 01, 10 and 11 respectively. (Denoted as 0b01, 0b10 and 0b11 below to distinguish from decimal numbers).
The bitwise AND-operator yields a 1 if and only if both bits are 1.
I.e. 1 & 1 = 1, 0 & 1 = 0, 1 & 0 = 0 and 0 & 0 = 0.
Truth-table:
& 0 1
-----
0 | 0 0
1 | 0 1
When opt equals 1 then only the first if-statement is true.0b01 & 0b01 = 0b01 (true) and 0b01 & 0b10 = 0b00 (false)
When opt equals 2 then only the second if-statement is true.0b10 & 0b01 = 0b00 (false) and 0b10 & 0b10 = 0b10 (true)
When opt equals 3 then both if-statements are true.0b11 & 0b01 = 0b01 (true) and 0b11 & 0b10 = 0b10 (true)
Anything not zero is true so all your conditions are met accordingly.
Solution 3:[3]
1 is 0b01, 2 is 0b10 and 3 is 0b11.
Therefore use the idiomatic
if (opt & 0b01){
// 1 or 3 selected
}
if (opt & 0b10){
// 2 or 3 selected
}
My binary literals 0b01 &c. are a compiler extension. If your compiler doesn't support them, then use an alternative such as the less clear 1, 2, and 3 or standard hexadecimal constants such as 0x01 &c. which can flag to readers of your code that bit locations are important.
Solution 4:[4]
You could us "else if" syntax as well.
#include <stdio.h>
int main()
{
int opt;
printf("(1) Option 1");
printf("\n(2) Option 2");
printf("\n(3) Both\n");
printf("Choice: ");
scanf(" %d", &opt);
if (opt == 3){
printf("\nBoth");
}
else if (opt == 2){
printf("\n2");
}
else{
printf("\n1");
}
return 0;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | |
| Solution 4 |
