while and if problem

This is a discussion on while and if problem within the C++ Programming forums, part of the General Programming Boards category; I have two programs both do the same thing but both when run gave totally different results. I am sure ...

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    164

    while and if problem

    I have two programs both do the same thing but both when run gave totally different results. I am sure there is a lesson to learn from this and that will teach you a fundamental difference between the ‘if’ and the ‘while’. Can anyone explain to me why both the programs ran differently as I am only a novice?

    Code:
    //Using if
    #include <iostream>  
    using namespace std;  
      
            void CountDown(int nValue)  
    {   cout << nValue << endl;
       if  (nValue > 0)  
       {  
      
        
       CountDown((nValue-1));}  
    }  
      
    void main(void)  
    {  
        CountDown(10);  
          
    }
    Result when run:
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    0

    Code:
    //Using while
    
    #include <iostream>  
    using namespace std;  
      
            void CountDown(int nValue)  
    {   cout << nValue << endl;
       while (nValue > 0)  
       {  
      
        
       CountDown((nValue-1));}  
    }  
      
    void main(void)  
    {  
        CountDown(10);  
          
    }
    Result when run:
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0^C

    Weird isn't it ?

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Not at all. It's all about variable scope. You never modify nValue (the recursive call uses a distinct variable), so the condition nValue > 0 holds always or never for any given call, so the innermost call (where nValue == 1) is stuck in an infinite loop, where it keeps calling CountDown(0), which prints the 0 you see.

    Please clean up your indentation; it's a mess.
    Last edited by CornedBee; 06-29-2008 at 11:19 AM.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    The first example is correct. Correct, but I wouldn't use recursion in this case. Loop would have been more "natural" (and of course, more efficient).

    Why is the second example printing only zeros ? Well, first, you didn't catch the top of the output, where you will see the normal "10, 9, 8 ... 1" sequence. And after the call to "Countdown(1)", which means that nvalue == 1 in this function call, well, the loop will always be true (because 1 > 0), so it will always make a "Countdown(0)" call, which will print the "0" value and return (since 0 > 0 is false, it won't enter the loop), and the calling function will again call "Countdown(0)" etc, etc...

    And also, when you say
    Code:
    I have two programs both do the same thing but both when run gave totally different results
    If they give totally different results, it's because they are not doing the same thing.

    And I agree that your indentation is messy.
    I hate real numbers.

  4. #4
    Registered User
    Join Date
    Nov 2007
    Posts
    164
    i dont understand ? please explain

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,899
    Your indentation isn't messy. For a lack of a better word, it sucks. Plain and simple.
    Here is how it should look like:

    Code:
    using namespace std;  
    
    void CountDown(int nValue)  
    {   
    	cout << nValue << endl;
    	if  (nValue > 0)  
    	{  
    		CountDown((nValue-1));
    	}  
    }  
    
    int main()
    {  
    	CountDown(10);  
    }
    
    //Using while
    
    using namespace std;  
    
    void CountDown(int nValue)
    {   
    	cout << nValue << endl;
    	while (nValue > 0)  
    	{  
    		CountDown((nValue-1));
    	}
    }  
    
    int main()
    {  
    	CountDown(10);  
    }
    And don't use void main!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Nov 2007
    Posts
    164
    Thanks Elysia for the word, it suites the indentation now

    but the problem isn't solved yet.

    Code:
    #include <iostream>
    using namespace std;
    
    void CountDown(int nValue)
    {
    	cout << nValue << endl;
    	while (nValue > 0)
    	{
    		CountDown((nValue-1));
    	}
    }
    
    int main()
    {
    	CountDown(10);
    }

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,899
    At point where nValue = 0, the call stack looks like:

    > Temp2.exe!CountDown(int nValue=0) Line 29 C++
    Temp2.exe!CountDown(int nValue=1) Line 33 + 0xc bytes C++
    Temp2.exe!CountDown(int nValue=2) Line 33 + 0xc bytes C++
    Temp2.exe!CountDown(int nValue=3) Line 33 + 0xc bytes C++
    Temp2.exe!CountDown(int nValue=4) Line 33 + 0xc bytes C++
    Temp2.exe!CountDown(int nValue=5) Line 33 + 0xc bytes C++
    Temp2.exe!CountDown(int nValue=6) Line 33 + 0xc bytes C++
    Temp2.exe!CountDown(int nValue=7) Line 33 + 0xc bytes C++
    Temp2.exe!CountDown(int nValue=8) Line 33 + 0xc bytes C++
    Temp2.exe!CountDown(int nValue=9) Line 33 + 0xc bytes C++
    Temp2.exe!CountDown(int nValue=10) Line 33 + 0xc bytes C++
    Temp2.exe!main() Line 39 + 0x7 bytes C++

    What happens when CountDown executes and nValue = 0? What happens when CountDown executes and nValue = 1?
    Ask yourself those questions.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Well, the best would be for you to run your program in a debugger. Visual Studio has a really easy to use debugger (that's one of the thing I really like from VS), but you could also run it in gdb. Or, you could add some code in your code and look at the output, example:

    Code:
    #include <iostream>
    using namespace std;
    
    void CountDown(int nValue)
    {
    	cout << " Entering CountDown with nValue = " << nValue << '\n';
    	cout << nValue << endl;
    	while (nValue > 0)
    	{
    		CountDown((nValue-1));
    		// Sleep(3) if you are on Windows (and #include <windows.h>)
    		// sleep(3) if you are on Linux (and #include <unistd.h>)
    	}
    	cout << " Exiting CountDown with nValue = " << nValue << '\n';
    }
    
    int main()
    {
    	CountDown(10);
    }
    I hate real numbers.

  9. #9
    Registered User
    Join Date
    Nov 2007
    Posts
    164
    What happens when CountDown executes and nValue = 0?
    Ans: When CountDown executes and nValue = 0, then the loop should end, as 0 is not > 0. But it doesn't

    What happens when CountDown executes and nValue = 1?
    Ans: When CountDown executes and nValue = 1, then the loop continues because 1 > 0, and it calls CountDown(0). So after the execution of CountDown(0) the loop should end. But wtf it doesn't


    When it makes a CountDown(0) call, it should print 0, yup, thats right, but after it it shouldn't enter the loop as the condition is false because nValue is not greater than 0.
    Last edited by manzoor; 06-29-2008 at 03:25 PM.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,899
    The loop does abort, but look at the call stack. You have several functions calls on top. Recursion.
    The nValue = 0 function ends, but nValue = 1 function continues.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    As I said before, when you call the function recursively, nValue is no the same. This is very important: just because a name is the same, and even the location of the name is the same, doesn't mean it's actually just one variable. Every time you call the function you get a new set of local variables, which are completely independent from all other sets.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21