If statement logic reverse - c++

bool x = someFuncThatReturnsTrueorFalse();
if (!x && (str1.length() != str2.length()) {
// do nothing
} else {
// do something
}
How would I rearrange the code above to eliminate the else statement?
I need to do nothing if bool = false and str1 and str2 have different lengths. Otherwise, I need to do something (e.g. function call).
For the life of me, I can't think of any way to change this. Let me know if you need further details.

The simplest way is putting !() around the condition.
bool x = someFuncThatReturnsTrueorFalse();
if (!(!x && (str1.length() != str2.length())) {
// do something
}
Another way is using De Morgan's laws: !(A && B) is equivalent to !A || !B.
bool x = someFuncThatReturnsTrueorFalse();
if (x || (str1.length() == str2.length()) {
// do something
}

There is nothing wrong leaving as is. The code will still compile

Related

Should I prefer two if statements over an if-else statement if the conditions aren't related?

So I know that generally speaking, I should prefer an else-if over and if if. But what if the two conditions aren't related? For example, these would be considered "related" conditionals:
if (line[a] == '{'){
openCurly = true;
}
else if (line[a] == '}'){
closeCurly = false;
}
Notice how the two conditionals in the if-statements are related in a way such that when one is true, the other must be false. This is because line[a] can either be { or } but not both.
Here is another example:
if (line[a] == '{')
{
openCurly = true;
}
else if ((line[a] == ';' && !openCurly) || (line[a] == '}' && openCurly))
{
DoSomething(line);
line = "";
}
The second condition will never evaluate to true if the first condition if true, so it makes sense to have an else-if. However, those two conditionals look vastly different.
So, should I prefer something like this?
if (line[a] == '{')
{
openCurly = true;
}
if ((line[a] == ';' && !openCurly) || (line[a] == '}' && openCurly))
{
DoSomething(line);
line = "";
}
You should use an else-if statement. This is because an if-else construct only checks the second statement if the first one doesn't evaluate to true.
In the example you give,
if (line[a] == '{')
{
openCurly = true;
}
else if ((line[a] == ';' && !openCurly) || (line[a] == '}' && openCurly))
{
DoSomething(line);
line = "";
}
replacing the else if with an if statement would result in the second condition being checked even if the first one is true, which is completely pointless and would also lose you some time.
In the future, make decisions to use else-if statements based on whether the conditions are mutually exclusive or not.
You could do something like this:
#include <stdint.h>
#define COMBINATION(x, y) ((uint16_t(x) << 8) | (uint16_t(y) << 0))
...
switch (COMBINATION(line[a], openCurly))
{
case COMBINATION('{', false):
...
break;
case COMBINATION(';', false):
case COMBINATION('}', true):
...;
break;
}
}
Some may say it's a bit of an overkill, but I think that it may actually help splitting up the logical operation of your program into a set of distinct cases, thus make it easier to handle each case precisely as desired.

Is there a way of doing a "post switch" like operation with bool?

I have a condition like the following where I just want to have the second bool be the trigger for a single time, since this condition is invoked relatively often I don't like the idea of doing the assignment of it being false every time the condition is true so, I tried to take advantage of the order of logical AND and OR and the post increment operator. But it appears to work don't do what I expected it to do. So is there a way to make a post state switch for this line?
where firstTitleNotSet is:
bool firstTitleNotSet;
if (titleChangedSinceLastGet() || (p_firstTitleNotSet && p_firstTitleNotSet++))
The idea is that the first part is the primary trigger and the second is the trigger that only has to trigger the first time.
While I easily could do
if (titleChangedSinceLastGet() || p_firstTitleNotSet)
{
firstTitleNotSet = false;
//...
}
I don't like this as it is reassigning false when ever the conditional block is invoked.
So is there some way of "post change" the value of a bool from true to false? I know that this would work the other way around but this would negate the advantage of the method most time being the true trigger and therefor skipping the following check.
Note: The reasons for me making such considerations isntead of just taking the second case is, that this block will be called frequently so I'm looking to optimize its consumed runtime.
Well, you could do something like:
if (titleChangedSinceLastGet() ||
(p_firstTitleNotSet ? ((p_firstTitleNotSet=false), true):false))
An alternative syntax would be:
if (titleChangedSinceLastGet() ||
(p_firstTitleNotSet && ((p_firstTitleNotSet=false), true)))
Either one looks somewhat ugly. Note, however, that this is NOT the same as your other alternative:
if (titleChangedSinceLastGet() || p_firstTitleNotSet)
{
p_firstTitleNotSet = false;
//...
}
With your proposed alternative, pontificate the fact that p_firstTitleNotSet gets reset to false no matter what, even if the conditional was entered because titleChangedSinceLastGet().
A more readable way than the assignment inside a ternary operator inside an or inside an if would be just moving the operations to their own statements:
bool needsUpdate = titleChangedSinceLastGet();
if(!needsUpdate && firstTitleSet)
{
needsUpdate = true;
firstTitleSet = false;
}
if(needsUpdate)
{
//...
}
This is likely to produce very similar assembly than the less readable alternative proposed since ternary operators are mostly just syntactic sugar around if statements.
To demonstrate this I gave GCC Explorer the following code:
extern bool first;
bool changed();
int f1()
{
if (changed() ||
(first ? ((first=false), true):false))
return 1;
return 0;
}
int f2()
{
bool b = changed();
if(!b && first)
{
b = true;
first = false;
}
return b;
}
and the generated assembly had only small differences in the generated assembly after optimizations. Certainly have a look for yourself.
I maintain, however, that this is highly unlikely to make a noticeable difference in performance and that this is more for interest's sake.
In my opinion:
if(titleChangedSinceLastUpdate() || firstTitleSet)
{
firstTitleSet = false;
//...
}
is an (at least) equally good option.
You can compare the assembly of the above functions with this one to compare further.
bool f3()
{
if(changed() || first)
{
first = false;
return true;
}
return false;
}
In this kind of situation, I usually write:
bool firstTitleNotSet = true;
if (titleChangedSinceLastGet() || firstTitleNotSet)
{
if (firstTileNotSet) firstTitleNotSet = false;
//...
}
That second comparison will likely be optimized by the compiler.
But if you have a preference for a post-increment operator:
int iterationCount = 0;
if (titleChangedSinceLastGet() || iterationCount++ != 0)
{
//...
}
Note that this will be a problem if iterationCount overflows, but the same is true of the bool firstTitleNotSet that you were post-incrementing.
In terms of code readability and maintainability, I would recommend the former. If the logic of your code is sound, you can probably rely on the compiler to do a very good job optimizing it, even if it looks inelegant to you.
That should work:
int firstTitleSet = 0;
if (titleChangedSinceLastGet() || (!firstTitleSet++))
If you wish to avoid overflow you can do:
int b = 1;
if (titleChangedSinceLastGet() || (b=b*2%4))
at the first iteration b=2 while b=0 at the rest of them.

Correct use of Syntax in if statement using && Operator and 2 variables

I have a quick question regarding proper use of syntax, basically i am trying to summarise these two if statements into one if statement.
if (sc.LastCallToFunction) {
if (p_LowRectanglesList != NULL) {
free(p_LowRectanglesList);
sc.PersistVars->i1 = 0;
}
if (p_HighRectanglesList != NULL) {
free(p_HighRectanglesList);
sc.PersistVars->i2 = 0;
}
return;
Would it be syntactically correct to rewrite this as:
if (sc.LastCallToFunction) {
if (p_LowRectanglesList || p_HighrectangleList != NULL) {
free(p_LowRectanglesList && p_HighRectanglesList);
sc.PersistVars->i1 && sc.PersistVars->i2 = 0;
}
return;
Or would the compiler not accept this / Is my Logic faulty?
you can't do it the way you have given
if (p_LowRectanglesList || p_HighrectangleList != NULL)
this logically ORs the first pointer ( treats it as true or false ) with the comparison of the seond pointer to NULL
free(p_LowRectanglesList && p_HighRectanglesList);
this logically &&s the pointers together and then tries to free the result of that operation. ie, you are trying to free "true" or "false"
sc.PersistVars->i1 && sc.PersistVars->i2 = 0;
this logically ands the two things together, which will result in true or false and then trys to assign 0 to it..... doesn't make any sense at all.
Also, in your original code....after the free, you should put p_LowRectanglesList=NULL;

If String's beginning inc spec Values

I'm trying to write a program that checks 15-16 digit inputs and see what bank they belong to. I'm not familiar with the language I'm coding in(c++), and would like some pointers. I know you can't copy and paste without the rest of the code, but it would be to long to post all of it. I just need a little adivce on a couple things.
Right now I have the program checking the length of the input and what the first two values of the string are. I would like to know if there is an easier way then what I have right now.
if(cLen==15 && c[0]== 3 && c[1]==4)
and
if(cLen==15 && c[0]== 3 && c[1]==7)
cause all I need is to find Strings that have the first two nums to be 34 or 37
secondly I need to check if the string has first values of 51 through 55
and lastly I need to check if the string contains 6011 at the beginning.
string validatebankcc(string c, int cLen, bool& ccOK) {
string bankcc;
if(cLen==15 && c[0]== 3 && c[1]==4)
bankcc = "AmericanExpress";
if(cLen==15 && c[0]== 3 && c[1]==7)
bankcc = "AmericanExpress";
if(cLen==16 && "6011 in beginning")
bankcc = "Discover";
if(cLen==16 && c[0]==5 && c[1]==1)
bankcc="MasterCard";
if(cLen==16 && c[0]==5 && c[1]==5)
bankcc="MasterCard";
if(c[0]==4)
bankcc="Visa";
else
bankcc = "Uknown Bank"
return bankcc;
bool got_length_and_prefix(string s, int desired_length, string desired_prefix) {
if (s.length() != desired_length) return false;
if (s.find(desired_prefix) != 0) return false;
return true;
}
string validatebankcc(string c, int /* cLen useless here*/, bool& ccOK) {
ccOK = true;
if (got_length_and_prefix(c, 15, "34")) return "AmericanExpress";
if (got_length_and_prefix(c, 15, "37")) return "AmericanExpress";
if (got_length_and_prefix(c, 16, "6011")) return "Discover";
if (got_length_and_prefix(c, 16, "51")) return "MasterCard";
if (got_length_and_prefix(c, 16, "55")) return "MasterCard";
if (c[0] == '4') return "Visa";
ccOK = false;
return "Unkown Bank";
}
Though overall design is bad. Returning bank name as string is crying for trouble (which also leads to useless ccOK flag, which can be replaced by BANK_UNKNOWN or smth like that. Passing string length along with string which known about it length also smells like trouble.
if (c.find("6011") != string::npos && c.find("6011") == 0) //"6011" in beginning
{
}
Firstly, you don't need to pass around the string length - there is a member function size() for that. Secondly, you should be passing by const &. Finally, you can use find_first_of to simplify this:
Hence your method will look something like this:
string validate_bank_cc(const string& c, bool& ccOk)
{
if((c.size() == 15) && (c.find_first_of("34") == 0))
return "AmericanExpress";
//etc...
}

Logical error with the || operator?

A part of my program (I can add more details if necessary) contains this line:
if((e->start->explored = false) || (e->end->explored = false)){
//do action...
}
This is part of a graph algorithm, where e is a directed edge with incident vertices "start" and "end." I would like the 'action' to happen if at least one of the incident vertices of e is unexplored, but this logic appears to be faulty. Although I used a small example and verified that, indeed, the start and end vertices of my edges were unexplored to start with, my overall function is going into an infinite loop.
So then I tested it like this:
if((e->start->explored = false) || (e->end->explored = false)){
//do action...
}
else cout << "FAIL";
...and, of course, it printed a screen of "FAIL." What is my logic error here?
You're assigning false to your properties instead of testing them against false. This is a mistake often made, and quite hard to debug. Change your = assignment operator to the equality operator ==:
if((e->start->explored == false) || (e->end->explored == false)) {
// Do action...
} else {
cout << "FAIL";
}
Instead of comparing the values to false, it's clearer to use the ! not operator instead. The inner brackets are done away with, too:
if(!e->start->explored || !e->end->explored) {
// Do action...
} else {
cout << "FAIL";
}
As the others have expounded you accidentally used assignment instead of comparison. However, the real solution is not to compare at all:
Comparing bool values to literals true and false is nonsensical!
Instead, write:
if(! e->start->explored || ! e->end->explored)
You have used the assignment operator = not the comparison operator ==.
You are assigning values here:
if((e->start->explored = false) || (e->end->explored = false)){
Should be:
if((e->start->explored == false) || (e->end->explored == false)){