I don't completely understand this code

357mag

Well-known member
Joined
Mar 31, 2023
Messages
75
Programming Experience
3-5
This code computes the integer powers of two going from 0 to 9. I was able to follow it for the first two cout statements:

2 to the 0 power is 1
2 to the 1 power is 2

But after that I lose it. It's a hard program for me to understand.

One thing I need to know is this: When you are working with a nested loop, does the inside loop (in my case the while loop) go to it's total completion, before the program goes back to the top of the outside loop (the for loop)? I was of the
understanding that the inside loop goes to completion before program flow goes back to the outside loop. But I don't know now. I'm currently doing this in C ++, but I will be doing it in C# too. Plus when I run the program I'm
getting an infinite loop and I don't know why that is.

The code is:

C#:
int main()
{
    int e;
    int result;

    for (int i = 0; 1 < 10; i++)
    {
        result = 1;
        e = i;

        while (e > 0)
        {
            result *= 2;
            e--;
        }

        cout << "2 to the " << i << " power is" << result << endl;
    }

    cout << endl;

    system("pause");
    return 0;
}
 
If I am correct, the very first time through the loop, the while loop does not even run. Because it's not true that 0 > 0. I think the second time the while loop will run. But I don't understand the e--. What is the purpose of that?

And when the while loop is done executing the second time through this, do we go back to the top of the code and i++ gets incremented to 1? And then we jump back into the while loop? If we don't go straight to the while loop again, but run the code in the for loop where result gets assigned the value of 1, we are never going to get the values of 2, 4, 8, 16 etc. So I'm thinking program control can't be going there.

I was wondering where program control goes once we are at the top of the code where the for loop header is. I guess I'm not sure where program control goes once i gets incremented in the for loop.
 
But I don't understand the e--. What is the purpose of that?

It's not csharp, strictly but it's still readable to us

e-- means "decrement e by 1".

Its purpose it to control the number of times the while loop body is run, ie the number of times that result is doubled



As an aside: It also, by definition, is an operations that returns a value and the value returned is what e was before it was decremented. The way to remember this is because the letter e is before the decrement

This means if you wrote:

int e = 10;
int x = e--;

x would end up as 10, e would be 9

You might also see it written as --e

Which has the same effect of decrementing e, but it returns the value of e after the decrement, so

int x = --e;

Would set x to 9

I point this out because it can be quite common to see loops written like:

while(e-- > 0) ...
while(--e > 0) ...

If e was 3 the first loop runs 3 times, the second runs two times. Can you work out why?

Further side note, you may see spacing removed thus:

while(e-->0)

Which kinda makes it look like there is some magic "e goes toward zero" arrow; it is however just "decrement e then loop if the value of e before the decrement, was greater than 0"



--

In terms of program flow you need to understand the for loop:

1734723826286.png


The int i = 0 is done just once, then the truth of 1<10 (probably a typo of i<10 but will work for this example, the real program will crash) is evaluated, it is true so the body of the for loop is run. At the end i++ increments i and the truth test is reevaluated (can you see why 1<10, which is a true/false test, will cause a problem?) and if true the body runs again

As a whole, the program looks like this for changing values of i:

1734723745501.png

i is 0, e is 0, e is -1, -1 not greater than 0, while loop does not run

i is 1, e is 1, 1 is greater than 0, while loop runs, e is 0, 0 is not greater than 0, while loop does not run

i is 2, e is 2, 2 is greater than 0, while loop runs, e is 1, 1 is greater than 0, while loop runs, 0 is not greater than 0, while loop does not run

--

Perhaps find a decent visual code editor that has a debugger that will allow you to step through the code and watch it
 
Last edited:
I understand the decrement operator. I guess I wasn't exactly clear. I'm having problems understanding how the code is working in general. Am I correct when I say that the very first time though the loop the while loop test condition will fail so the first time through the loop the statements in the while loop will not even run?

I am unclear in understanding the program flow.

After the cout statement has printed "2 to the ...power", does program control go back to the beginning of the outer for loop? Or does program control go back to the inner while loop?
 
The cout is part of the outer for loop

See my edit, which may have crossed with your post, with the red line/blue numbers overlaid on the code
 
But it is not true that 0<0. The very first time through the loop it seems to me that the while loop will fail, so none of those statements in the body of the while will execute. I don't see how e can even get decremented.

And I did type the wrong thing. I should have typed i < 10.
 
Last edited:
You are correct, the first time through the for loop, the while loop does not run at all

I wouldn't use the word "fail" - failure is more like an error that causes the code to stop and proceed no further

It's simply an expected and coded-for circumstance that i is 0, hence e is 0, hence e>0 is false, hence the while loop doesn't run

Soon i will be 1, and e will be 1 and the while loop will run once

Then i will be 2, e 2, while twice

--

e will only be decremented if the while loop runs, the while only runs if e > 0

The code naturally arranges the condition that the loop will run a certain number of times ; if e was 50, the while loop would run 50 times
 
@357mag : See you are getting the hang of things! Looks like you are doing great analysis of code and asking the right set of questions to confirm your observations. Well done!

We'll me a programmer of you yet! Of course, there's also Jonathan Coulton who was a programmer who decided that he'd rather play the guitar. :cool:
 
How can we get the answers for the result variable when we are going to the top of the loop and result is always being reset to 1?
We need the result variable to contain the values 1, 2, 4, 8, 16 etc.
I don't see how that result variable will contain those values if it is always being reset to 1.
 
The current value of result is printed out on line 17. When execution returns to the top of the loop at line 8, then result is set back to 1.

As an experiment, you can add a line of code between lines 7 and 8 to see what happens before it is reset back to 1:
C#:
cout << "At the top of the loop, result is " << result << endl;

Think of the cout as a speaker. Once sound has been emitted by the speaker there is no recalling or replacing it. So when the code at line 17 executes, it can only show the current value of result and there is no replacing that line that's been sent to the console.
 
Thank You for your help. Unfortunately, I still don't see how we are going to get the numbers, 1, 2, 4, 8, 16 if result always gets reset to 1 in the for loop.
But my head is weary. I think I will walk away from this code example for awhile. Perhaps come back to it later on. Thank You So Much.
 
Let's try rearranging the code a little bit and write it in C# since this is a C# forum after all:

C#:
static int GetPowerOfTwo(int exponent)
{
    int product = 1;
    while (exponent > 0)
    {
        product *= 2;
        exponent--;
    }
    return product;
}

static void Main()
{
    for(int i = 0; i < 10; i++)
    {
        int result = GetPowerOfTwo(i);
        Console.WriteLine($"2 to the {i} power is {result}.");
    }
}

Notice the basic structure of the for loop within Main() and all the loop does is call a method that computes the power of two for a given exponent.

i is passed into the GetPowerOfTwo() method. The parameter exponent takes on the value i each time the method is called. Within the method, the variable product starts off with the value of 1, and then gets multiplied by 2 exponent times to get the power 2. That product is returned to the caller and put into the result variable.

Next this code can be refactored as:
C#:
static void Main()
{
    for(int i = 0; i < 10; i++)
    {
        int exponent = i;    // exponent parameter takes the value of i

        int product = 1;
        while (exponent > 0)
        {
            product *= 2;
            exponent--;
        }

        int result = product;    // result takes the computed product value
        Console.WriteLine($"2 to the {i} power is {result}.");
    }
}

Well, result variable in pretty useless in the code above. So we can just print out the value of product directly.
C#:
static void Main()
{
    for(int i = 0; i < 10; i++)
    {
        int exponent = i;

        int product = 1;
        while (exponent > 0)
        {
            product *= 2;
            exponent--;
        }

        Console.WriteLine($"2 to the {i} power is {product}.");
    }
}

And we can rename product to result just to match up with the original C++ code.
C#:
static void Main()
{
    for(int i = 0; i < 10; i++)
    {
        int exponent = i;

        int result = 1;
        while (exponent > 0)
        {
            result *= 2;
            exponent--;
        }

        Console.WriteLine($"2 to the {i} power is {result}.");
    }
}

And that C++ code from post number 1 looks to have been written by a C programmer who is transitioning into C++. The C convention is to declare variables as close to the top of a function because original C required that. (Ironically, they didn't move i as well which original C would have also required. And so we now rewrite the code some more:
C#:
static void Main()
{
    int exponent;
    int result;

    for(int i = 0; i < 10; i++)
    {
        exponent = i;

        result = 1;
        while (exponent > 0)
        {
            result *= 2;
            exponent--;
        }

        Console.WriteLine($"2 to the {i} power is {result}.");
    }
}

And another old C convention is to make variable names as short as possible to help out the old C compilers, as well as if the variable for loops, also make it as short as possible. So we get:
C#:
static void Main()
{
    int e;
    int result;

    for(int i = 0; i < 10; i++)
    {
        e = i;

        result = 1;
        while (e > 0)
        {
            result *= 2;
            e--;
        }

        Console.WriteLine($"2 to the {i} power is {result}.");
    }
}

And it doesn't really matter whether, e = i; or result = 1; comes first, and so we get:
C#:
static void Main()
{
    int e;
    int result;

    for(int i = 0; i < 10; i++)
    {
        result = 1;
        e = i;
        while (e > 0)
        {
            result *= 2;
            e--;
        }

        Console.WriteLine($"2 to the {i} power is {result}.");
    }
}
 
Modern C++ is not "C-with-classes". It has its own idioms and conventions which have diverged from C. Both C# and C++ share the convention and idiom of declaring variables as close to where they are used. This is different from classic C where all variables needed to be declared at the top of each scope, and a lot of people copied the K&R style of putting variables at the function scope because it helped prevent aliasing bugs.

Also modern C++ and C# tend to follow SOLID programming principles. S is for Single Responsibility Principle. So breaking out the ComputePowerOfTwo() as a separate function/method is the suggested way to do things. ComputePowerOfTwo()'s only job is to compute a power of 2. The Main() only job is to show the powers of 2 from 0 to 9.

Just my opinion: but I don't think that Schildt C++ book is helping you.
 
Thanks Much. Right now I can't much concentrate. I just found out that someone got my credit card number and made a purchase for over $400.00. There is more too. Someone bought two items on eBay using my PayPal account! I've already spoken with both my credit card company and PayPal. It looks like it will be taken care of properly. But it' s really upsetting.

The program I posted is one of Herb's programs.
 
Ack! Take care of higher priorities. Coaching will be here when you need it.
 
Back
Top Bottom