[SOLVED]Noob needs help with C code episode 五

I’ve been teaching myself the basics of programming with this book I bought. Enjoying it so far, I get it for the most part, but am a true beginner. In this next episode of, “I can’t figure out what is going on.” I am using if statements.

When my variable testFor == 10, the first if statement is supposed to fire but for one reason or another it defaults to the else. I scanf to read an int from the keyboard, store it in num1. I pass num1 to my ifStatement function. A local variable testFor = num1. When testFor == 10, I get the default case. Seems to work for all other cases though. Screen shots and code for posterity. I have some seemingly random printf in there but I was trying to see what was being assigned to num1 and testFor…shows 10.

IDK why if those were assigned 10 the if (testFor == 10) does not fire.

Any help is appreciated. Up to this point, I have learned some important things from each help thread I’ve put up. Look forward to your feedback.

#include <stdio.h>
#include <stdbool.h>
#include <math.h>

void getData (int* num1);
void ifStatement (int num1);

int main (void)
{
    int num1 = 0;
    
    getData(&num1);
    
    printf("%d\n", num1);
    ifStatement(num1);
    
    return 0;
}

void getData (int* num1)
{
    printf("Be careful with the integer you type.  Choose from 0-10\n");
    scanf("%d", num1);
    
    return;
}

void ifStatement (int num1)
{
    int testFor = num1;
    float squareTest = 0;
    float prod = 0;
    
    printf("%d\n", testFor);
    
    if (testFor == 10)
        {
            squareTest = pow(testFor, 2);
        }
    else ;
    
        if (testFor == 9)
            {
                printf("RE-ROLL! Enter a number 0-10\n");
                scanf("%d", &testFor);
                
            }
        else ;
        
            if (testFor == 2 || testFor == 3)
                {
                    prod = testFor * 99;
                    printf("Multiply by 99 and we get %.2f\n", prod);
                }
            else
                {
                    printf("ERROR: YOU DIDN'T ENTER A NUMBER 0-10 DID YOU? JUMP IN A LAKE.");
                }

    return;
}

Here is what I get in console:

broken2

The code enters the “then” branch, as intended. The problem stems from the semicolon after the else. As semicolons terminate code lines in C you’ve effectively made an empty “else” branch.

Thus

  • the if's condition is evaluated (to true)
  • the “then” branch is executed, but has no observable effect
  • the (empty!) “else” branch is skipped
  • the code after the “else” is executed

Remove the semicolons after the else keywords and add curly braces around the code that’s supposed to be executed when the condition is false


Most of the errors you’ve posted thus far are very easy to catch with a debugger. I highly recommend looking into one so you can watch what your code is actually doing.

1 Like

It’s already been said, but you don’t put a semicolon after an else statement usually (read: always unless you’r writing super weird code on purpose). C will happily execute a semicolon, like any other line of code, but it doesn’t do anything. That’s why while (1); is a valid line of code (technically); instead of a normal loop body to execute forever, it just does a no-operation forever.

Here’s a few examples to help with the syntax:

if (myCondition)
    firstThing;
else
    secondThing;
alwaysThing;

This will do firstThing if myCondition is true, xor secondThing if it’s false. Xor because it will do one or the other but never both; if it takes the first branch it will skip the second and vice versa. Regardless, it will do alwaysThing after that.

Note the absence of curly braces. If there’s only one line of code (as in one semicolon), you don’t need them. You can still use them, but it only affects readability. The tabs are essential for readability, but similarly, don’t affect compilation at all. If I put a line of code after firstThing without adding curly braces, you would probably get a compiler error (too lazy to verify), since firstThing would be the end of the entire if statement, the new line would happen always, since it’s outside the conditional, and the else wouldn’t make any sense without an if immediately before it, hence the error.

if (myCondition) {
    firstThing;
    if (otherCondition) {
        otherThing;
    }
    secondThing;
    } else {
    alternateThing;
    alternateThingStep2;
}
alwaysThing;

It’s a little more busy with the curly braces, so be grateful I tabbed it correctly (since, of course, there are no rules in C). The curly braces accomplish variable scoping, so stuff you declare inside a block is cleared off the stack when you leave the block, but the property that matters here is that it binds together all the lines of code inside into one. Instead of just doing firstThing and leaving the if statement, the if statement controls the entire first block as a whole. So if myCondition is false, it skips straight to the else, and does both alternateThings in order. If myCondition is true, though, then we get a chance at the nested if statement. If otherCondition is true, then otherThing will be executed between firstThing and secondThing. But if otherCondition is false, it only affects otherThing. firstThing and secondThing are the only lines executed, since the inner if statement only controls otherThing.

It’s easier to read if it’s less spaced out (fewer newlines, I only use them to separate blocks of related code) and less tabbed in. That can be tough to do but counting more than like 3 or 4 tabs from the left margin sucks. A switch statement might work better for your particular code; a case for 10, a case for 9, a case for 2 and one for 3 that map to the same code, and a default. But if you want to use if and else, you were probably looking for this:

if (cond1) {
    branch1;
} else if (cond2) {
    branch2;
} else if (cond3) {
    branch3;
...
} else if (condN) {
    branchN;
} else {
    branchDefault;
}
backToNormal;

Note that they aren’t nested. If you trigger one if statement, it skips the rest because of the else's tying the if's together. It’s a tiny bit faster, but also guarantees that you only take one branch, if that’s what you want.

Using a debugger to step through your code might help you a lot with this kinda stuff. If you’re using CLI stuff, you’ll have to learn gdb I think. It’s a lot easier to use an IDE for this.

1 Like