Stroustrup ch2 section 2.3.2 example

Discussion in 'C++' started by arnuld, Oct 30, 2006.

  1. arnuld

    arnuld Guest

    i am trying to understand the mentioned programme, i modified it a
    little so that i could understand it better. here is the code & output:

    // Stroustrup - Tour of C++

    #include <iostream>

    int main() {
    int tries = 1;

    while(tries < 4) {
    std::cout << "Do you want to proceed [y/n]: ";
    char get_ans = 0;
    std::cin >> get_ans;

    switch(get_ans) {
    case 'y':
    return true;
    case 'n':
    return false;
    default:
    std::cout << "Sorry, did not get that.\n";
    tries = tries + 1;
    }

    std::cout << "I will take that for a NO.\n";
    return false;
    }

    std::cout << "print of *int main()* \n";
    return 0;
    }


    -------------------OUTPUT ------------------------------

    hurd@debian:~/programming/cpp$ g++-3.4 02_232-1.cpp

    hurd@debian:~/programming/cpp$ ./a.out
    Do you want to proceed [y/n]: y

    hurd@debian:~/programming/cpp$ ./a.out
    Do you want to proceed [y/n]: n

    hurd@debian:~/programming/cpp$ ./a.out
    Do you want to proceed [y/n]: j
    Sorry, did not get that.
    I will take that for a NO.

    hurd@debian:~/programming/cpp$
    -----------------------------------------------------------

    i understand 3 things here:

    1.) when i enter 'y' or 'n' /return/ breaks-out from the /main()/, not
    from /switch/ or /while/. it is clear as the statement just above
    /return 0/ never prints. it means /return/ breaks out from the whole
    function & not from the innermost loop. why?

    (i expected /return/ to break out of /switch/ only )

    2.) from (1), it means i can use /return/ anywhere & it will break-out
    from the nested-loops immediately even when i will have 3 nested loops
    & i use /return/ in innermost loop.

    3.) /switch/ executes only for once.

    4.) there is no use of variable /tries/ here as /return/ always causes
    /while/ to execute only once.
    arnuld, Oct 30, 2006
    #1
    1. Advertising

  2. arnuld wrote:
    > [..]
    > i understand 3 things here:
    >
    > 1.) when i enter 'y' or 'n' /return/ breaks-out from the /main()/, not
    > from /switch/ or /while/. it is clear as the statement just above
    > /return 0/ never prints. it means /return/ breaks out from the whole
    > function & not from the innermost loop. why?


    That's how the "return" statement is defined. What do you mean by
    "why"? Why is the language defined the way it's defined? Read "Design
    and Evolution of C++", perhaps it's going to get clearer.

    > (i expected /return/ to break out of /switch/ only )


    OK, now my turn to ask: why? What other language do you know that
    has that feature? Logically speaking 'return' always makes the current
    *function* in to stop processing immediately and *return* the control
    to the *caller* of that function.

    > 2.) from (1), it means i can use /return/ anywhere & it will break-out
    > from the nested-loops immediately even when i will have 3 nested loops
    > & i use /return/ in innermost loop.


    It will *return* from the function to the caller of that function,
    regardless of the nested-ness of any loops or if's or switch'es.

    > 3.) /switch/ executes only for once.


    Yes, you understand correctly. And you also observed it.

    > 4.) there is no use of variable /tries/ here as /return/ always causes
    > /while/ to execute only once.


    That's unfortunate, but yes, it seems to be extraneous. Are you sure
    you copied the example correctly? I don't have TC++PL handy.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Oct 30, 2006
    #2
    1. Advertising

  3. arnuld

    Daniel T. Guest

    "arnuld" <> wrote:

    > i am trying to understand the mentioned programme, i modified it a
    > little so that i could understand it better.


    IMHO you didn't modify it "a little" you made major changes to the logic
    of the program.

    The actual code from 3rd ed. of the book:

    bool accept3()
    {
    int tries = 1;
    while (tries < 4) {
    cout << "Do you want to proceed (y or n)?\n"; // write question
    char answer = 0;
    cin >> answer; // read answer
    switch (answer) {
    case 'y':
    return true;
    case 'n':
    return false;
    default:
    cout << "Sorry, I don't understand that.\n";
    tries = tries + 1;
    }
    }
    cout << "I'll take that for a no.\n";
    return false;
    }

    > here is the code & output:
    >
    > // Stroustrup - Tour of C++
    >
    > #include <iostream>
    >
    > int main() {
    > int tries = 1;
    >
    > while(tries < 4) {
    > std::cout << "Do you want to proceed [y/n]: ";
    > char get_ans = 0;
    > std::cin >> get_ans;
    >
    > switch(get_ans) {
    > case 'y':
    > return true;
    > case 'n':
    > return false;
    > default:
    > std::cout << "Sorry, did not get that.\n";
    > tries = tries + 1;
    > }
    >
    > std::cout << "I will take that for a NO.\n";
    > return false;
    > }
    >
    > std::cout << "print of *int main()* \n";
    > return 0;
    > }
    >
    > i understand 3 things here:
    >
    > 1.) when i enter 'y' or 'n' /return/ breaks-out from the /main()/, not
    > from /switch/ or /while/. it is clear as the statement just above
    > /return 0/ never prints. it means /return/ breaks out from the whole
    > function & not from the innermost loop. why?


    You would have to ask the designers of the C language that question.

    > 2.) from (1), it means i can use /return/ anywhere & it will break-out
    > from the nested-loops immediately even when i will have 3 nested loops
    > & i use /return/ in innermost loop.


    Right. You might also want to investigate uses of the 'break' statement.

    > 4.) there is no use of variable /tries/ here as /return/ always causes
    > /while/ to execute only once.


    That's because you put the "I'll take that for a No." and return false
    inside the while loop. Note that in the original code from the book,
    these two lines are outside the while loop.

    --
    To send me email, put "sheltie" in the subject.
    Daniel T., Oct 30, 2006
    #3
  4. arnuld

    arnuld Guest

    > Victor Bazarov wrote:

    > That's how the "return" statement is defined. What do you mean by
    > "why"? Why is the language defined the way it's defined?


    aaaoooh!

    > Read "Design and Evolution of C++", perhaps it's going to get clearer.


    i will read it after 3-6 months of programming with C++.

    > > (i expected /return/ to break out of /switch/ only )


    > OK, now my turn to ask: why?


    Ha...Haa..

    > What other language do you know that
    > has that feature? Logically speaking 'return' always makes the current
    > *function* in to stop processing immediately and *return* the control
    > to the *caller* of that function.


    ok *current function*. got it.

    > > 4.) there is no use of variable /tries/ here as /return/ always causes
    > > /while/ to execute only once.

    >
    > That's unfortunate, but yes, it seems to be extraneous. Are you sure
    > you copied the example correctly? I don't have TC++PL handy.


    it is correct. Damn Sure
    arnuld, Oct 30, 2006
    #4
  5. arnuld wrote:
    >> Victor Bazarov wrote:
    >> [..]
    >> Are you sure
    >> you copied the example correctly? I don't have TC++PL handy.

    >
    > it is correct. Damn Sure


    Judging from Daniel T's post, you didn't...
    Victor Bazarov, Oct 30, 2006
    #5
  6. arnuld

    arnuld Guest

    > arnuld wrote:

    > > That's unfortunate, but yes, it seems to be extraneous. Are you sure
    > > you copied the example correctly? I don't have TC++PL handy.

    >
    > it is correct. Damn Sure


    well, "Daniel T." is responsible for killing my "Damn Sure-edness" ;-)

    my programme was wrong. i corrected it.
    arnuld, Oct 30, 2006
    #6
  7. * Victor Bazarov:
    > arnuld wrote:
    >
    >> 4.) there is no use of variable /tries/ here as /return/ always causes
    >> /while/ to execute only once.

    >
    > That's unfortunate, but yes, it seems to be extraneous. Are you sure
    > you copied the example correctly? I don't have TC++PL handy.


    Arnuld's code:

    // Stroustrup - Tour of C++

    #include <iostream>

    int main() {
    int tries = 1;

    while(tries < 4) {
    std::cout << "Do you want to proceed [y/n]: ";
    char get_ans = 0;
    std::cin >> get_ans;

    switch(get_ans) {
    case 'y':
    return true;
    case 'n':
    return false;
    default:
    std::cout << "Sorry, did not get that.\n";
    tries = tries + 1;
    }

    std::cout << "I will take that for a NO.\n";
    return false;
    }

    std::cout << "print of *int main()* \n";
    return 0;
    }

    If the user enters (lowercase) 'y' or 'n' then yes, the corresponding
    'case' of the 'switch' statement is executed, and there a 'return'
    statement is executed and the function, er, returns, immediately.

    If the user enters anything else then the 'default' clause of the
    'switch' is executed, and increases the value of 'tries' by 1 (we say
    it's incremented). Execution then reaches the closing } of the 'while'
    loop's body, wereupon it jumps to the top of the loop again, and the
    continuation condition (involving 'tries') is checked again.

    If you have a visual debugger then you can check this out directly,
    running the program statement by statement in the debugger. I'm told
    there is such a debugger in Microsoft's free (except download time)
    Visual Studio Express. If you're running Windows, that is.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Oct 30, 2006
    #7
  8. arnuld

    Salt_Peter Guest

    arnuld wrote:
    > i am trying to understand the mentioned programme, i modified it a
    > little so that i could understand it better. here is the code & output:
    >
    > // Stroustrup - Tour of C++
    >
    > #include <iostream>
    >
    > int main() {
    > int tries = 1;
    >
    > while(tries < 4) {
    > std::cout << "Do you want to proceed [y/n]: ";
    > char get_ans = 0;
    > std::cin >> get_ans;
    >
    > switch(get_ans) {
    > case 'y':
    > return true;
    > case 'n':
    > return false;
    > default:
    > std::cout << "Sorry, did not get that.\n";
    > tries = tries + 1;
    > }
    >
    > std::cout << "I will take that for a NO.\n";
    > return false;
    > }
    >
    > std::cout << "print of *int main()* \n";
    > return 0;
    > }
    >
    >
    > -------------------OUTPUT ------------------------------
    >
    > hurd@debian:~/programming/cpp$ g++-3.4 02_232-1.cpp
    >
    > hurd@debian:~/programming/cpp$ ./a.out
    > Do you want to proceed [y/n]: y
    >
    > hurd@debian:~/programming/cpp$ ./a.out
    > Do you want to proceed [y/n]: n
    >
    > hurd@debian:~/programming/cpp$ ./a.out
    > Do you want to proceed [y/n]: j
    > Sorry, did not get that.
    > I will take that for a NO.
    >
    > hurd@debian:~/programming/cpp$
    > -----------------------------------------------------------
    >
    > i understand 3 things here:
    >
    > 1.) when i enter 'y' or 'n' /return/ breaks-out from the /main()/, not
    > from /switch/ or /while/. it is clear as the statement just above
    > /return 0/ never prints. it means /return/ breaks out from the whole
    > function & not from the innermost loop. why?


    because neither switch nor while are functions. These are loops with a
    conditional expression with the purpose of controlling the sequence of
    the program.

    >
    > (i expected /return/ to break out of /switch/ only )
    >
    > 2.) from (1), it means i can use /return/ anywhere & it will break-out
    > from the nested-loops immediately even when i will have 3 nested loops
    > & i use /return/ in innermost loop.


    Yes, return will terminate/exit whatever function it was called in,
    regardless of the loops involved. Synctaticly, you could think of the
    loops as nothing else but conditional scopes with their own stack.
    In other words, there is more going on than meets the eye.
    Obviously, if you return from within any scope, all the active scopes
    in the function() cease to exist. That is, any automatic variable in
    those scope(s) has its d~tor invoked. Returning from an inner scope
    does not interrupt that process - on the contrary.

    Unlike loops and scopes, functions return a state which may very well
    be void. Loops and scopes don't return anything, they just live and
    die, but die they do.

    To prove the stack:
    #include <iostream>

    int main()
    {
    int i(0);
    { // a do_it_once loop
    int i(1);
    { // another do_it_once loop
    int i(2);
    std::cout << "(inner loop) i = " << i << std::endl;
    // returning here ends all scopes
    }
    std::cout << "(mid loop) i = " << i << std::endl;
    }
    std::cout << "(outer loop) i = " << i << std::endl;
    return 0;
    }

    /*
    (inner loop) i = 2
    (mid loop) i = 1
    (outer loop) i = 0
    */

    Try see what happens if you access ::i instead from within an inner
    loop. This is important because those scopes are really anonymous
    namespaces.

    >
    > 3.) /switch/ executes only for once.
    >
    > 4.) there is no use of variable /tries/ here as /return/ alwaa parallel universeys causes
    > /while/ to execute only once.


    To respect the purpose of the program, the above should be:

    #include <iostream>

    int proceed()
    {
    std::cout << "lets do it!\n";
    // do some work here
    return 0;
    }

    int main() {
    int tries(0);

    while(tries < 4) {
    std::cout << "Do you want to proceed [y/n]: ";
    char get_ans = 0;
    std::cin >> get_ans;

    switch(get_ans) {
    case 'y':
    return proceed();
    case 'n':
    std::cout << "aborting as requested.\n";
    return 0;
    default:
    std::cout << "Sorry, did not get that.\n";
    ++tries;
    }
    }
    std::cout << "I will take that for a NO.\n";
    return 0;
    }
    Salt_Peter, Oct 30, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. arnuld

    Stroustrup section 2.5.1

    arnuld, Oct 31, 2006, in forum: C++
    Replies:
    3
    Views:
    301
    Default User
    Oct 31, 2006
  2. arnuld
    Replies:
    13
    Views:
    508
    Default User
    Nov 8, 2006
  3. arnuld
    Replies:
    2
    Views:
    291
    arnuld
    Nov 8, 2006
  4. arnuld
    Replies:
    6
    Views:
    382
    arnuld
    Nov 8, 2006
  5. Alf P. Steinbach
    Replies:
    22
    Views:
    710
    Alf P. Steinbach
    Dec 20, 2009
Loading...

Share This Page