Else if statement executing unexpectedly, behaving as else statement [duplicate] - c++

This question already has answers here:
Is (4 > y > 1) a valid statement in C++? How do you evaluate it if so?
(5 answers)
Closed 5 years ago.
I'm working on a simple function to convert ascii codes to array indexes, and I'm have a bit of trouble with the else-if statement.
int getIndex(char character) {
int code = int(character);
int index = -1;
if (code == int(' ')){
index = 26;
} else if (int('a') <= code <= int('z')) {
index = code - int('a');
}
return index;
}
The if condition works fine and fires on spaces, but the else if statement fires in every other case, regardless of whether the character is in the range a to z or not. Is there a problem I can't see with the condition?

c++ doesn't support expressions with multiple comparisons (like, e.g., python does). You need to break the expression in the else if branch into two expression with the logical and (&&) operator between them:
if (code == int(' ')){
index = 26;
} else if (int('a') <= code && code <= int('z')) {
// Here -----------------^
index = code - int('a');
}
return index;

Related

C++ What are the conditions of short circuit evaluation? [duplicate]

This question already has answers here:
A warning - comparison between signed and unsigned integer expressions
(6 answers)
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 6 months ago.
if (i - word.size() >= 0 && dp[i - word.size()] && s.substr(i - word.size(), word.size()) == word)
dp[i] = true;
i - word.size() >= 0 is the condition that I was using to prevent an out-of-bound indexing. The expectation was that if the condition was not satisfied, the equation would short circuit and the reference dp[i - word.size()] would not be happen.
But the reference happened regardless of the first condition. Only when I changed the code to the following, it started to short circuit.
int lookback = i - word.size();
if (lookback >= 0 && dp[lookback] && s.substr(i - word.size(), word.size()) == word)
dp[i] = true;
Why does the second code short circuit while the first one doesn't? I've read that if the logical operators && and || are overloaded, short circuiting doesn't happen, but that doesn't seem to be the case here and I can't figure out why it's not happening.
Here's the full code for context
bool wordBreakFaulty(string s, vector<string>& wordDict) {
int n = s.size() + 1;
vector<bool> dp(n, false);
dp[0] = true;
for (int i = 1; i < dp.size(); ++i) {
for (auto& word : wordDict) {
if (i - word.size() >= 0 && dp[i - word.size()] && s.substr(i - word.size(), word.size()) == word)
dp[i] = true;
}
}
return dp.back();
}

Same code, one works one doesn't. What's different? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 12 months ago.
Improve this question
i'm an beginner programmer, this is my first time posting. I'm currently writing a snake game in c++. Most of the game wasn't so hard to implement but when it came to the tail of the snake the entire program broke. I spent like 2 hours trying to figure out what was wrong and then i decided to try to rewrite the problematic code.
From my understanding i haven't changed a thing but now it works. Can someone explain to me what changed?
Here is the code, the commented one is not working the other works fine:
else {
bool eCoada = false;
for (int s = 0; s <= ntail; s++)
{
if (tail[s].height == j && tail[s].width == k)
{ eCoada = true; break; }
}
if (eCoada == false) cout << " ";
else cout << "o";
}
/* else {
bool eCoada = false;
for (int s = 0;s <= ntail; s++)
{
if (tail[s].height==j && k==tail[s].width==k)
{ eCoada = true; break; }
if (eCoada==false) cout << " ";
else cout << "o";
}
}*/
Also i should mention that this code is a part of a function, if you want me to post the full code i will do so.
k==tail[s].width==k is not the same as tail[s].width == k. You may think you've written something like (k == tail[s].width) && (tails[s].width == k. But C++ doesn't automatically put in && operators like that. What actually happens is that the associativity of the == operator is left to right. So what that actually means is
(k == tails[s].width) == k
Assuming k and tails[s].width are ints, that means (k == tails[s].width) is a bool. The comparison between that and k will be checking if k is 0 or 1, instead of checking if it matches the width as intended.
Another difference is in the placement if your if(eCoada==false) line.
In your working code, it's after the for loop finishes, which means that it only executes once.
In your broken code, it's inside the for loop, which means that every time the loop executes it prints a space. It also means that because you break out of the loop immediately upon setting eCoada to true, you never execute the else branch and never print an o.
C++, nor any other language that I know of, doesn't allow multiple comparisons in one statement.
You can't say is x == y == z,
you must break them up.
if(x ==y && y == z)

How is the value of b unchanged? [duplicate]

This question already has answers here:
Is short-circuiting logical operators mandated? And evaluation order?
(7 answers)
Closed 6 years ago.
How is the value of b unchanged?
#include <iostream>
int main()
{
int a = 5, b = 10;
if (++a || ++b)
std::cout << a << b;
system("PAUSE");
return 0;
}
The output is 610. But how?
here's how the 'if' statement works:
if(condition1 || condition2 || condition 3){
//do this
}
now if condition1 is true (which in your code, it is since a!=0), the execution straightaway moves inside the block without checking 2 and 3.
If you wish to increment b as well, try && in place of ||

Two variables that are true return false in (tmp1 == tmp2). Why? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I just came upon one problem. I wanted to compare whether my Eratostenes's Sieve contains prime numbers or not. In the code i have this line
if (sieve[2] == is_prime(2)) // returns false
printf ("true");
Now, sieve[2] is a boolean and it's value is true (I even checked in the array, so there's no doubt about it). is_prime(2) is a boolean aswell (I also checked).
Now my problem. The line presented above returns false. Yes - it returns false even though it's statement is:
if ( true == true ) // which normally returns true
printf ("true");
However, after removing one equation sign:
if ( sieve[2] = is_prime(2) ) // returns true
printf ("true");
This statement returns true.
Can someone briefly explain how does one equation mark work in this case in comparison to ==?
Thanks in advance
EDIT
is_prime:
bool is_prime(int x) {
unsigned int i,j,k;
if (x < 2) return false;
else {
for (i=2; i!=x; i++) {
if (x == i) return true;
else if (x % i == 0) return false;
}
}
}
sieve:
const int n = 10000;
bool sieve[n+1];
.
.
unsigned long int i;
sieve[0] = sieve[1] = false;
for (i=2; i<=n; i++) sieve[i] = true;
for (i=2; i*i<=n; i++) {
if (sieve[i]) {
unsigned tmp = 2*i;
while (tmp <= n) {
sieve[tmp] = false;
tmp += i;
}
}
}
[EDIT2]
The problem was with "is_prime(x)" Changed loop condition from "i!=x" to "i<=x"
Sorry for the trouble and thanks for the answers
UPDATE
bool is_prime(int x) {
unsigned int i,j,k;
if (x < 2) return false;
else {
for (i=2; i!=x; i++) {
if (x == i) return true;
else if (x % i == 0) return false;
}
}
}
Your is_prime() (above) is broken, with undefined behaviour, as when x is 2 (or indeed any actually prime number) it reaches the end of the function without having a return statement - the i!=x test means the x == i inside the loop can never be true.
is_prime(2) it's likely to return effectively random results (based on left over stack or register content / in your documented output it's seeming "returning" x itself, presumably because your ABI uses the same CPU register or stack address to pass in the argument and pass back the function's return value).
Specifically for 2, flow enters the first else clause, then with i=2 the first i!=x test fails and the for loop immediately exits... there's no return after the for's scope. Minimally corrected code (faster implementations are possible, but keeping the simplicity and intended logic):
bool is_prime(int x)
{
if (x < 2) return false;
for (int i = 2; i < x; ++i)
if (x % i == 0)
return false;
return true;
}
Equivality / ==
With sieve[2] == is_prime(2) it's checking they have the same value - possibly after converting one of the values to enable the comparison, but you say they're both booleans so that's not necessary. This would yield a "true" value for the if when they're both true or both false.
Now my problem. The line presented above returns false. Yes - it returns false even though...
That doesn't make any sense... I suggest you add the following before the if statement to check the variables' values:
std::cout << "sieve[2] " << sieve[2] << " (bool)" << (bool)sieve[2]
<< ", is_prime(2) " << is_prime(2) << std::endl;
I even checked in the array, so there's no doubt about it
Be wary of mistakes like seeing the array content displayed ala { true false true false } and thinking [2] is the second value... it's actually the third. as array indexing starts at 0.
Assignment / =
With sieve[2] = is_prime(2) you're assigning the value of is_prime(2) into sieve[2], and the if statement is deemed "true" if that value is deemed true in a boolean context (i.e. it's a boolean with value true, or a non-0 number or pointer etc.). For most data types, the execution flow of if (sieve[2] = is_prime(2)) ... is the same as simply if (is_prime(2)) ..., but of course it also modifies sieve[2].
It assigns the right hand operand to left, and returns the left operand.Since you are assigning true to your variable, it evaluates to true. If you set your variable to false, you don't get the output, e.g:
bool x;
if(x = false)
printf("this won't be printed");
Here the equal affect the left operator with the value of the right operator then test the value. So the result must be the value of the right operator.
Your loop in is_prime will never run for the check x == i will be true, because it runs as long as x != i. Those two conditions are mutually exclusive.
That means the function will end without a return statement, which leads to undefined behavior.
This
if ( sieve[2] = is_prime(2) )
contains an assignment, not a comparison.
As the value of an assignment is the value assigned, it is true whenever is_prime(2) is.
However, let's look at your is_prime and see what happens if we pass it a 2...
bool is_prime(int x) {
unsigned int i,j,k;
So far, so good, but j and k are never used, so they shouldn't really be here.
if (x < 2) return false;
2 isn't less than 2, so we'll continue...
else {
for (i=2; i!=x; i++) {
OK, set i = 2, and compare it to x which is 2, and... oops, i is equal to x, so we'll abandon the loop immediately...
if (x == i) return true;
else if (x % i == 0) return false;
}
}
... and fall through here, where we're not returning a value like we promised, and causing undefined behaviour.
}
So, your program is undefined (you really should switch on compiler warnings, or start listening to them).
And this happens on every number that is prime.
You can rewrite the loop like this:
for (i=2; i <= x; i++) {
if (x == i) return true;
else if (x % i == 0) return false;
}
or
for (i=2; i < x; i++) {
if (x % i == 0) return false;
}
return true;
Why does if (is_prime(2)) appear to work?
(Since this code is undefined, the following is largely speculation and should only be taken with suitable measures of salt.)
Often, when a function is supposed to return something but doesn't, the calling function will just grab whatever is stored in the place where the return value should have been and use that.
This value is in this case very likely not the same as the bit pattern that represents true, so will compare unequal to true, in if (is_prime(2) == true).
It will however, also very likely, not be the bit pattern that represents false either, so will be considered true in a conditional, if(is_prime(2)).

Counting # of words in a line [duplicate]

This question already has answers here:
C++ function to count all the words in a string
(10 answers)
Closed 9 years ago.
This is what I am trying to do, this is not nearly the entire program I am making just a small portion. This part is counting the # of words of what I enter.
string s;
getline(cin, s);
for (unsigned int i = 0; i < s.length(); i++)
{
if (s[i] == ' ' || s[i] == '.')
{
numWords++;
}
}
This obviously works if someone enters a correct line with a period at the end. I can't think of how to get it to recognize the end of line character though, incase they don't put a period.
Why not just start the numWords counter on 1 and only count the spaces?
You can simply count the number of " " in your line and add that to 1. That's all.
bool previousSpace = false;
for (unsigned int i = 0; i < s.length(); i++)
{
if (isspace(s[i]) || s[i] == '.')
{
if (previousSpace == false)
{
numWords++;
previousSpace = true;
}
}
else
{
previousSpace = false;
}
}
cout << numWords + (previousSpace ? 0 : 1) << endl;
This considers more than one consecutive spaces. The key here is to use isspace function.
Could this be the same that you are after? Count the number of times each word occurs in a file or this already duplicate one Word count program in C++ duplicate?