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

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)

Related

A program that checks whether a number is between 10 and 50 in c++ [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 months ago.
Improve this question
i have a task in c++. I have to write program checks whether a number is between 10 and 50. I wrote something but it errors, can you help me please.
#include <iostream>
using namespace std;
int main()
{
int a;
cout << "enter number";
cin >> a;
if ( 10 < a < 50)
cout << "True";
else
cout << "False";
return 0;
}
The expression 10 < a < 50 is actually the same as (10 < a) < 50.
So it compares the boolean true or false result of 10 < a with the integer value 50.
The comparison will always be true, since 10 < a will be either 0 or 1 when converted from false or true, respectively.
You need to make two separate comparisons, chained together with the logic AND operator &&, like 10 < a && a < 50.
You can't write if statements like a < b < c. You can compare only two things at the moment, so, you have to change your if statement like that
if (a > 10 && a < 50){
// correct
} else {
// not correct
}
In C++, && is a logic AND, while || is a logic OR. Now, this statement means "if a is more than 10 AND a is fewer than 50.
Update
Actually, you can compare a < b < c, but this will lead to behavior that you probably are not expecting. Instead of that, will be better to use logic AND and logic OR to separate such a comparements into several, much simple comparements like a < b AND b < c.

minimum number of moves required to convert a given into a lucky number [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
You are given a number, at a time either you can increase a number by 1 or decrease by 1 it is considered as one move find the minimum number of moves required to convert a given into a lucky number. A number is called lucky if all the digits in it are even.
I have writtern the code but I am not sure if it is correct. Can anybody please confirm me?
#include<bits/stdc++.h>
using namespace std;
int count(int n)
{
int count = 0;
while (n != 0)
{
n = n / 10;
++count;
}
return count;
}
int firstDigit(int n)
{
// Remove last digit from number
// till only one digit is left
while (n >= 10)
n /= 10;
// return the first digit
return n;
}
int main()
{
int n;
cin >> n;
int i,j,ans=0;
int x = count(n);
while(x--)
{
if(firstDigit(n)%2 != 0)
{
if(firstDigit(n) == 9)
{
ans = ans + pow(10,x);
n = n-pow(10,x);
}
else
{
ans = ans + pow(10,x);
n = n + pow(10,x);
}
}
else
n = n - pow(10,x);
}
cout << ans << endl;
}
Edit:
I found it is giving wrong answer at 100. Can you please help me in finding out the mistake
Not all code can easily be tested, thats why you should strive to write testable code right from the start (instead of first writing it all and then try to confirm correctness). In your case testability could benefit a lot from moving most logic from main into a dedicated function:
int minimal_steps(int input) {
....
}
Once you have that, you can either call it in main with user supplied input just as you do it now, but you can also write tests more easily:
void test() {
assert( minimal_steps(2222) == 0);
assert( minimal_steps(2221) == 1);
...etc...
}
Once you got into the habit of testing your code (you should also write tests for count and firstDigit) you may consider to use a testing framework to automate tests.
PS: It isnt wrong, but it is such a waste of CPU cycles that it is worth mentioning (actually it was already mentioned in a comment). You do not need to compute pow(10,x) in a loop where x is the loop counter. Consider that you are computing 10^2 almost as many times as the loop has iterations. Also 10^3 is the same in every iteration. Instead you should only update with *10 (in case x is incremented) or /10 when x decrements between iterations. Moreover, pow is for floating-points, not for integers.

Why was `unsigned int` causing the program to crash? [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 6 years ago.
Improve this question
I had to make a program that checks if two words can be obtained one from the other by permutating the letters. I wrote the code as you can see below and I struggled quite a long time to find out why the program is crashing, and at some point I had the idea to change the fundametal type of these variables from unsigned int (unsigned int code = 0, i, j, counter = 0, ok = 1;) to integer (int code = 0, i, j, counter = 0, ok = 1;) and now it works properly but I don't know what changed so that now it works. I know (please correct me if I'm wrong) that unsigned int goes from 0 (including 0) to a very large number. All the variables were not going under 0, so I don't know why it didin't work in the unsigned int version and how the fundamental type changing solved the crash.
#include<iostream>
#include<string.h>
using namespace std;
int main()
{ char word1[50], word2[50];
unsigned int code = 0, i, j, counter = 0, ok = 1;
cout << "Type in the first word and then press ENTER:";
cin.getline(word1, 50);
cout << "Type in the second word and then press ENTER:";
cin.getline(word2, 50);
cout << endl;
if (strlen(word1) == strlen(word2)) //If the two words don't have the same lenght, it's impossible to obtain one word of the other by permutating it's letters.
{ for (i = 0; word1[i]; i++) /*This nested FOR will generate a number in the code variable. The first digit will indicate how many times will the letter word1[0] be found in word2,
the second digit will indicate how many times will the letter word1[1] be found in word2 and so on until the end of word1*/
{ counter = 0;
for (j = 0; word2[j]; j++)
if (word1[i] == word2[j])
counter += 1;
code = code * 10 + counter;
}
i = strlen(word1) - 1;
while (i >= 0 && ok) /*In this loop we are checking if the code is valable also for the word1 itself. If it is, it means that the words can be obtained one of the other by permutating the letters*/
{ counter = 0;
for (j = strlen(word1) - 1; j >= 0; j--)
if (word1[i] == word1[j])
counter++;
if (counter == code % 10)
ok = 1;
else
ok = 0;
code = code / 10;
i--;
}
if (ok)
cout << "Yes, the words can be obtained one of the other by permutating the letters.";
else
cout << "No, the words can not be obtained one of the other by permutating the letters.";
}
else
cout << "No, the words can not be obtained one of the other by permutating the letters.";
cin.get();
}
Part of your code goes:
while (i >= 0 && ok) { /* ...stuff here... */ --i; }
With an unsigned, if i is 0 and you decrement it, it will become the maximum unsigned value. As a result, i is always greater than or equal to 0 and the while loop keeps executing.
My guess is that is what is happening, and then, when you access word[i] you are accessing outside of the bounds of the array and crashing.
the problem is probably from the following code:
for (j = strlen(word1) - 1; j >= 0; j--)
because you defined j as unsigned int the for loop goes on for ever and never breaks.
Beginners mistake: Consider that if i is an unsigned int, i >= 0 will always be true. It cannot be false. If you set i to 0 and then subtract 1, you will get a very large positive number.
If your compiler didn't give you a warning, ask someone to show you how to turn more warnings on.

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)).

Multiple if statements in C++

I'm doing the first project euler problem and I just did this
#include <iostream>
using namespace std;
int main(){
int threes =0;
int fives = 0;
int both = 0;
for (int i = 0; i < 10; i++){
if(i%3==0){
threes += i;
}
if(i%5==0){
fives += i;
}
if ( i % 5 == 0 && i % 3 == 0){
both += i;
}
}
cout << "threes = " << threes << endl;
cout << "fives = " << fives << endl;
cout << "both = " << both << endl;
cout << " threes + fives - both = " << endl;
int result = (threes + fives) - both;
cout << result<< endl;
return 0;
}
My professor recently corrected me for doing this in a different problem saying something about else statements,
but I don't understand WHY i have to add else in front of the next if. for what its worth I have another version with else if(i%5){ fives += .... }
and they both work and get me the right answer.
My question is whats inherently wrong with this way of thinking, is it stylistic or am I not thinking logically about something?
If it works, why use switch statements ever?
The only thing that I see wrong with your implementation is that in the case where the number is both a multiple of 3 and a multiple of 5 not only is the both variable incremented but the fives and threes variables are also incremented. Based on what the professor described I believe he wants you to use an else-if so that the both variable is the only one that is incremented when you pass in a number that is both a multiple of 3 and a multiple of 5.
The reason you get the correct answer both ways is because you are only going to 10 in the for loop, if you increase it to i <= 15 you will get fives and threes being 1 higher than I think he intended.
For example:
for( int i = 0; i < 10; i++ )
{
if( ( ( i % 3 ) == 0 ) && ( ( i % 5 ) == 0 ) )
{
both++;
}
else if( ( i % 3 ) == 0 )
{
threes++;
}
else if( ( i % 5 ) == 0 )
{
fives++;
}
}
The else branch in an if-else statement is only executed if the if branch is false. If you just have two if statements in a row, they'll both be executed, which can be a waste. In the below code, the else prevents the second computation from running if the first is satisfied.
if (expensive_computation1()) {
...
}
else if (expensive_computation2()) {
...
}
Additionally, it's clearer to humans reading the code whether both if statements should be allowed to run or whether only one should.
In this case, maybe you really want this:
if (i % 5 == 0 && i % 3 == 0) {
both += i;
} else if (i % 3 == 0) {
threes += i;
} else if (i % 5 == 0) {
fives += i;
}
(why you do += i instead of ++ I don't know but you didn't explain, so I just copied it)
In your code, threes and fives were incremented even if it would also increase both, which depending on your problem may not be what you want. If you do the if/else way I've just presented, only one of the three variables is increased.
Why use if-else instead of multiple if's?
if-else & if would achieve the same results but if-else achieves them in a performance enhanced way. with multiple if's every if condition will have to be checked. With if-else only one conditional check will have to be performed and the rest of the conditions just don't need to be checked at all.
This would not affect a small program like the one you have but it will sure have some impact in potentially expensive function being called repeatedly over and over again.
If it works, why use switch statements ever?
With nested if-else conditions the code is hard to read and understand. The switch-case construct helps to represent the conditions in a much easier to read & understand format.
To me it looks like stylistics. You can use some autoreformating tool that follows certain established stylistic look (K&R, ANSI, GNU, etc.)
For example astyle is such tool, http://astyle.sourceforge.net/ - just reformat your code with it, and you might have a happy professor.