So as part of a coding challenge I tried to make a Fizz Buzz program in C++ without looking at the solution. For those of you who don't know, it should be a loop that replaces any number divisible by 3 with Fizz, any number divisible by 5 with Buzz, and any number divisible by both with FizzBuzz:
1
2
Fizz
4
Buzz
6
7
8
Fizz
Buzz
11
Fizz
I'm almost there with the code below, however, i'm a little annoyed that even though I want the loop to stop entirely at 100, the way i've set up the program means that an extra 1 gets added to i after the loop has ended. Is there a way of stopping my FizzBuzz program from going past 100?
#include <iostream>
using namespace std;
int main () {
for (int i = 1; i < 100; ++i){
if (i % 3 == 0 && i % 5 == 0){
cout << "FizzBuzz\n";
i = i + 1;
}
if (i % 3 == 0){
cout << "Fizz\n";
i = i + 1;
}
if (i % 5 == 0){
cout << "Buzz\n";
i = i + 1;
}
cout << i << "\n";
}
}
So I fixed your code a little bit:
int main()
{
for (int i = 1; i < 101; ++i)
{
if (i % 3 == 0 && i % 5 == 0)
cout << "FizzBuzz\n";
else if (i % 3 == 0)
cout << "Fizz\n";
else if (i % 5 == 0)
cout << "Buzz\n";
else
cout << i << "\n";
}
}
Every time you do i = i + 1;, it's kinda useless because your loop does that. Also, I put everything is an if else chain, instead of and if if chain. That way only on statement will execute at any giving time. Also changed the max to 101 instead of 100 since the for loop will stop at 101 and not print the result of 101.
Hope this helps :)
In c++, variables have a lifetime, called their scope, and after their lifetime expires they are deleted. The i that is defined in the loop declaration has the scope constrained by the closing brace "}" of the for loop. Due to this, the variable i does not exist after the loop, only during. However in the code you have provided, the problem is that you are incrementing i multiple times. In your for loop you increment i every time the body of the for loop is executed, but within that body you increment i when it is divisible by 5 or 3 or both or neither. You can remove all of the i = i + 1; statements and remove most of the bugs.
Related
I have been programming in C++ for the past 3 years, and I have always used the continue keyword in loops with success. But right now, a simple code of mine with continue is not working properly. Here is the code that is showing the problem:
int main()
{
int num = 2, result = 0;
while (num > 1 && num < 50)
{
if (num % 2 != 0)
{
result += num;
}
else
{
continue;
}
num++;
}
cout << "The result is: " << result << endl;
return 0;
}
As stated above, this does not print anything on the console. When I remove the else statement with continue in it, it successfully calculates the result and prints the said result. Does anyone have any idea why the given code is not working correctly (or why the loop in it does not break)? Any sound answer would be much appreciated.
Loop is indeed continuing (continue works properly) correctly
Initially, num = 2, so if condition fails and goes to else. So it will call continue. Then again the loop starts from the beginning with num = 2. This continues forever.
In short, num value is not changing and if condition always fails.
It's a very simple issue. Look at this block of code properly:
else
{
continue;
}
Due to continue, n++ is never called because due to the non-changing value of n, num % 2 != 0 is always false. This is resulting in an infinite loop.
So to fix this issue, just remove the above block of code:
#include <iostream>
int main()
{
int num = 2, result = 0;
while (num > 1 && num < 50)
{
if (num % 2 != 0)
{
result += num;
}
/*else
{
continue;
}*/
num++;
}
std::cout << "The result is: " << result << std::endl;
return 0;
}
Also, consider not using the following in your code:
using namespace std;
..as it's considered as a bad practice. For more info on this, look up why is "using namespace std" considered as a bad practice.
You just have to remove your else part because of no use and terminated cause of continue keyword.
int main()
{
int num = 2, result = 0;
while (num > 1 && num < 50)
{
if (num % 2 != 0)
{
result += num;
}
num++;
}
std::cout << "The result is: " << result << std::endl;
return 0;
}
Since continue is just a thinly disguised goto, rewriting the loop with explicit gotos might make it clearer:
start:
if (num > 1 && num < 50)
{
if (num % 2 != 0)
{
result += num;
}
else
{
goto start;
}
num++;
goto start;
}
Now you see clearly that num isn't incremented when num % 2 != 0 is false.
Just remove the else branch.
I am trying to code a simple macro which based on a condition either calls break or continue in the loop in which it is called. Below is the code:
#include <iostream>
#define BC_IF_EVEN(BC) if(i % 2 == 0) BC
using namespace std;
int main() {
int i = 0;
while(i++ < 30) {
if(i < 15)
BC_IF_EVEN(continue);
else
BC_IF_EVEN(break);
cout << i << " ";
}
cout << endl;
}
The output that I am looking for is: 1 3 5 7 9 11 13 15, but the above code outputs: 1 3 5 7 9 11 13 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 because the else condition in main() gets applied to the if condition in the BC_IF_EVEN macro.
A simple fix is to put scope braces for the if condition in main(), but I do not want to enforce that because the user should be allowed to code in regular way.
N.B. I cannot put a do { .. } while(false) loop in the macro (which is a standard trick to allow semicolons after macro calls in conditionals because the break and continue sent via BC get applied to this inner loop.
Is there an easy way to get the required output without modifying the main() function?
#define BC_IF_EVEN(BC) if (i % 2 != 0); else BC
but really WHY?
Don't invent obscure macros in an attempt to justify your obscure loops. Frequent use of continue and break inside loops is a certain sign of poor program design.
Here's how to fix the program:
When the amount of items you iterate through is known in advance, use a for loop, as they are usually easier to read and harder to mess up.
Since you check if a number is even no matter in which way the program branches, might as well move that check outside the if-else.
for(int i=0; i<30; i++)
{
if(i%2 == 0) // even
{
if(i < 15)
continue;
else
break;
}
cout << i << " ";
}
Now look at the conditions and what the program actually does. This doesn't make sense at all. All it does is to print the odd numbers between 0 and 14 in a very obscure way. Instead, you probably wanted a program which prints the odd numbers between 0 and 15.
Apply common sense: Loop from 0 to 15. Check each number to see if it is odd. If so, print it. Otherwise ignore it.
for(int i=0; i<=15; i++)
{
if(i%2 != 0)
cout << i << " ";
}
Alternatively, don't bother with even numbers at all:
for(int i=1; i<=15; i+=2)
{
cout << i << " ";
}
This is why functions were created, just create a function to check if it is even or odd and return a true if even and false if odd. Macros are ugly when you can do it simply another way. Please for the love all legacy maintainers make readable code.
eg:
// Example program
#include <iostream>
using namespace std;
bool checkeven(int i)
{
if( i % 2 != 0)
return false;
else
return true;
}
int main()
{
for(int i = 0; i < 30; i++) //while(i++ < 30) is readable, but I think this is even easier
{
if(i < 15)
{
if(checkeven(i))
continue;
}
else
{
if(checkeven(i))
break;
}
cout << i << " ";
}
}
Use curly brackets even if you have the only line in if/else statement. In this case you'll fully control the workflow.
The other advantage of this approach is that if you need to comment out the line in if/else statement you'll just put // in the start of the line.
// wrong workflow
if ( expr )
// commented out for debug issues
//do_when_expr();
do_whatever();
// right workflow
if ( expr )
{
// commented out for debug issues
//do_when_expr();
}
do_whatever();
In your case it would be:
#define BC_IF_EVEN( BC ) if (i % 2 == 0) { BC; }
...
if(i < 15)
{
BC_IF_EVEN(continue)
}
else
{
BC_IF_EVEN(break);
}
Try this
#define BC_IF_EVEN(BC) ( { if(i % 2 == 0) BC; } )
You just need an extra pair of curly braces to restrict the scope for your inner if block. Following should work:
#define BC_IF_EVEN(BC) {if(i % 2 == 0) BC;}
Also do not use ';' while using macro:
if(i < 15)
BC_IF_EVEN(continue) //No semicolon
Or if you want use semicolon for code consistency then an extra pair of braces has to be put:
#define BC_IF_EVEN(BC) ({if(i % 2 == 0) BC;})
I have the following code example and I cannot figure out why it displays 123.
Since these are integers I understand the decimals are not displayed. But I expected it to show 3, 2(.3), 1(.23) (in the opposite order). When n goes below 10 everything stops after the final cout... right?
#include <iostream>
using namespace std;
void recursion(int n) {
if (n < 10) cout << n;
else {
recursion(n / 10);
cout << n % 10;
}
}
int main() {
recursion(123);
return 0;
}
Well, you call with 123 as n, the function executes the statement:
if (n < 10) // its false, so it continues with else:
else {
recursion ( n /10 ) // recursive call n/10 = 123/10 = 12 (as it's int)
...
It will continue like this, recursively calling with n being 12
recursion (n/10) // second recursion call n=12, so n/10 = 1
then the function is executed, with n being 1 so smaller than 10
if (n < 10) // its true
cout << n; // 1 gets printed
else // no, the rest is skiped
...
then it returns from recursion. So we're back in the context where n was 12. The next statement to be executed in that context is :
cout << n %10; // prints 12 % 10, which is 2
then, continuing like this, similarly it will print 123%10, which is 3. In conclusion, the 123 that is printed has nothing to do with the 123 entered as input.
I think you wanted to do :
...
else {
cout << n % 10; // first print to see the count down
recursion(n / 10); // then recurse
}
But you have to learn using a debugger. As long as you don't, put some extra cout to visualize what's happening.
When I Build and run my code it instantly returns 0 saying programing was successful, however i want it to display all the numbers from 100 to 200 that are divisible by 4.
Here's my code...
#include <iostream>
using namespace std;
int main()
{
int num = 200;
int snum;
cout<<"The following numbers are all divisble by 4 and are inbetween 100 and 200\n";
while(num<99)
{
snum = (num % 4) ;
cout<<snum<<endl;
cout<<num<<endl;
if(snum = 0)
{
cout<< num << endl;
}
else
{
}
num--;
}
return 0;
}
The while condition should be while (num > 99) instead of while(num<99)(false at the beginning)
The if condition should be if (snum == 0) instead of if(snum = 0)(= is assignment, not equal operator)
The else part has nothing, you may delete it. I added some other notes in the comments below.
while (num > 99)
{
snum = num % 4 ; // no need for the parenthesizes
if (snum == 0)
{
std::cout<< num << std::endl;
}
--num; //pre-increment is preferred, although doesn't matter in this case
}
Your loop never executes because the condition
(num<99)
is already false from the start. You probably meant
(num>99)
Also, the if statement condition
(snum = 0)
sets snum to zero, always returning zero, so you probably meant
(snum == 0)
You set num to be 200:
int num = 200;
Then you only run the loop if and when the number is less than 99:
while(num<99)
What do you expect will happen?
This is not how you do an equals-test in C:
if(snum = 0)
In C, equality is checked with ==:
if(snum == 0)
In fact, what you have (if (snum = 0)) will NEVER be true, so your if-statement will NEVER be executed.
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.