Thread: Order of Operations Question

  1. #1
    chix + guns > * chix/w/guns's Avatar
    Join Date
    Jul 2004
    Posts
    15

    Order of Operations Question

    Just out of curiosity, in the code below, whenever the add(), sub(), mul(), and div() functions are called, do they return 0 after main() has been called, or do they function more like batch files in which until main() has finished or terminated the next line is not run in those functions?

    For example:

    Code:
    @echo off
    echo This program runs the windows calculator.
    c:\windows\calc.exe
    exit
    In the batch file above, the exit command is not run until c:\windows\calc.exe has been terminated. Is this the same in C++?

    Here is the code in question:

    Code:
    #include <iostream.h>
    int add();
    int sub();
    int mul();
    int div();
    int main()
    {
    	int input;
    	cout<<"Please select an operation:"<<endl;
    	cout<<"1. Addition"<<endl;
    	cout<<"2. Subtraction"<<endl;
    	cout<<"3. Multiplication"<<endl;
    	cout<<"4. Division"<<endl;
    	cout<<"5. Exit"<<endl;
    	cin>>input;
    	switch (input)
    	{
    	case 1: add();
    		break;
    	case 2: sub();
    		break;
    	case 3: mul();
    		break;
    	case 4: div();
    		break;
    	case 5: return 0;
    	}
    }
    int add()
    {
    	int x, y;
    	cout<<"Please input two numbers to be added together."<<endl;
    	cin>>x>>y;
    	cout<<"The result is: "<<x+y;
    	main();
    	return 0;
    }
    int sub()
    {
    	int x, y;
    	cout<<"Please input a number to be subtracted from another."<<endl;
    	cin>>x>>y;
    	cout<<"The resul is: "<<y-x;
    	main();
    	return 0;
    }
    int mul()
    {
    	int x, y;
    	cout<<"Please input two numbers to be multiplied together."<<endl;
    	cin>>x>>y;
    	cout<<"The result is: "<<x*y;
    	main();
    	return 0;
    }
    int div()
    {
    	int x, y;
    	cout<<"Please a number to be devided by another."<<endl;
    	cin>>x>>y;
    	cout<<"The result is: "<<x/y;
    	main();
    	return 0;
    }

  2. #2
    chix + guns > * chix/w/guns's Avatar
    Join Date
    Jul 2004
    Posts
    15
    Sorry for the double post, but I was wondering if my tests were correct.

    To see if return 0 was run after main() was called by the various add(), sub(), mul(), and div() functions, I tried the following in main().

    Code:
    cout<<"1. Addition"<<add()<<endl;
    Now with that I should be able to see the output that the add() function creates, and a 0 on the end, because it outputs the returned value in the cout function. Though whenever I do this I get the normal output, and then no 0, and it runs the add() function again because a call to it is in main() which is called from add() (creating a never ending loop basically, thank god (bill gates, pun intended) for adding ctrl+c into DOS). So shouldn't that mean that return 0 in the add() function doesn't run until main() is terminated. Which means that return 0 in add() is never run because when main() is terminated then the entire program is terminated, or is it possible for code to execute after main() is terminated?

  3. #3
    VA National Guard The Brain's Avatar
    Join Date
    May 2004
    Location
    Manassas, VA USA
    Posts
    903

    hi

    your code looks good


    allow me to try to offer a couple of suggestions:


    1.) each individual function definition does not have to "return zero." What I would recommend, is that you make your functions "void" functions.. so they do not have to return any value

    Code:
    //Function Prototypes
    
    void add();
    void sub();
    void mul();
    void div();
    So now.. your function definitions will look similar to this..

    for example
    Code:
    void add()
    {
    	int x, y;
    	cout<<"Please input two numbers to be added together."<<endl;
    	cin>>x>>y;
    	cout<<"The result is: "<<x+y;
    	main();	
    }

    2.) This is kinda knit-picky.. but instead of using objects named, "x" and "y".... try focusing on, "self documenting code" technique.. for example:

    Code:
    int div()
    {
    	int x, y;
    	cout<<"Please a number to be devided by another."<<endl;
    	cin>>x>>y;
    	cout<<"The result is: "<<x/y;
    	main();
    	return 0;
    }
    could be:

    Code:
    void div()
    {
         int first_number, second_number;
    	
         cout<<"Please a number to be devided by another."<<endl;
         cin >> first_number >> second_number;
         cout<<"The result is: "<< (first_number / second_number);
    	
         main();
    }
    first_number and second_number have a little more meaning than 'x' and 'y'



    3.) insert "using namespace std;" after your preprocessor directive:

    Code:
    #include<iostream>
    using namespace std;
    also.. notice that I changed #include<iostream.h> to #include<iostream> which is now the modern convention... (the .h suffix is used mainly with older compilers)

    4.) I'm not sure if you are familiar with the "do/while" loop structure.. but it is a good way to make your program more robust.. allowing your switch case structure to be executed as many times as desired. Here is some of my own example code:

    Code:
    #include<cstdlib>	//Provides "EXIT_SUCCESS" and "system( )"
    #include<iostream>	//Provides "cin" and "cout"
    #include<cctype>	//Provides "toupper( )"
    	
    using namespace std;
    
    
    
    int main()
    {
    
    data stack;
    
    char choice = 'x';
    
    system("cls");
    
    	do
    	{
    		try
    		{
    			stack.print_menu();
    			choice = toupper(get_user_command());
    			switch(choice)
    			{
    		
    				case 'A':	stack.push();
    							break;
    
    				case 'R':	stack.pop();
    							break;
    
    				case 'V':	stack.view_array();
    							break;
    		
    				case 'E':	stack.erase_array();
    							break;
    
    				case 'Q':	exit_message();
    							break;
    		
    				default:	throw choice;
    			}		
    
    		}
    			
    		catch(char choice)
    		{
    			cout << "\n\t" << choice << " is an invalid entry.  Please try again." << endl;
    		}
    
    		cout << endl;
    		system("pause");	
    		system("cls");
    
    	}while (choice != 'Q');
    
    
    	
    
    return EXIT_SUCCESS;
    
    }
    Hope this helps shed some light on your question
    Last edited by The Brain; 07-13-2004 at 08:09 AM.
    • "Problem Solving C++, The Object of Programming" -Walter Savitch
    • "Data Structures and Other Objects using C++" -Walter Savitch
    • "Assembly Language for Intel-Based Computers" -Kip Irvine
    • "Programming Windows, 5th edition" -Charles Petzold
    • "Visual C++ MFC Programming by Example" -John E. Swanke
    • "Network Programming Windows" -Jones/Ohlund
    • "Sams Teach Yourself Game Programming in 24 Hours" -Michael Morrison
    • "Mathmatics for 3D Game Programming & Computer Graphics" -Eric Lengyel

  4. #4
    chix + guns > * chix/w/guns's Avatar
    Join Date
    Jul 2004
    Posts
    15
    Thanks a lot on the tips! I am just starting out and I can take all the help I can get.
    Last edited by chix/w/guns; 07-13-2004 at 07:54 AM.

  5. #5
    Registered User major_small's Avatar
    Join Date
    May 2003
    Posts
    2,787
    just some words about the brain's code: don't use Macros when possible... it's usually better to return 0 than to return EXIT_SUCCESS... and stay away from the system commands. for beginning code it's okay, but definately move away from it. if you use a system command, people can easily make your code do bad things.

    system("pause"); can be replaced by cin.get()

    you also don't need the main() at the end of the void functions, and in this case, I would rather read x/y than the_first_integer_passed_by_value/the_second_integer_passed_by_reference_denoting_th e_value_of_the_greatest_integer_derived_from_a_pre vious_series_of_events

    and to answer the OP: those functions do not run after main, but in it. functions run when they are called, not necessarily where they appear in your code. when your program runs, main is called, and then while main is running another function will be called in necessary. that function does what it does, and then eventually main will end and return 0.

    a run of your program doesn't even mean that all the functions will be run.
    Last edited by major_small; 07-13-2004 at 07:50 AM.
    Join is in our Unofficial Cprog IRC channel
    Server: irc.phoenixradio.org
    Channel: #Tech


    Team Cprog Folding@Home: Team #43476
    Download it Here
    Detailed Stats Here
    More Detailed Stats
    52 Members so far, are YOU a member?
    Current team score: 1223226 (ranked 374 of 45152)

    The CBoard team is doing better than 99.16% of the other teams
    Top 5 Members: Xterria(518175), pianorain(118517), Bennet(64957), JaWiB(55610), alphaoide(44374)

    Last Updated on: Wed, 30 Aug, 2006 @ 2:30 PM EDT

  6. #6
    chix + guns > * chix/w/guns's Avatar
    Join Date
    Jul 2004
    Posts
    15
    I see what you are saying major_small.
    Quote Originally Posted by The Brain
    your code looks good

  7. #7
    VA National Guard The Brain's Avatar
    Join Date
    May 2004
    Location
    Manassas, VA USA
    Posts
    903

    good stuff

    good tips major_small.. i'll take 'em
    • "Problem Solving C++, The Object of Programming" -Walter Savitch
    • "Data Structures and Other Objects using C++" -Walter Savitch
    • "Assembly Language for Intel-Based Computers" -Kip Irvine
    • "Programming Windows, 5th edition" -Charles Petzold
    • "Visual C++ MFC Programming by Example" -John E. Swanke
    • "Network Programming Windows" -Jones/Ohlund
    • "Sams Teach Yourself Game Programming in 24 Hours" -Michael Morrison
    • "Mathmatics for 3D Game Programming & Computer Graphics" -Eric Lengyel

  8. #8
    Compulsive Liar Robc's Avatar
    Join Date
    Jul 2004
    Posts
    149
    >don't use Macros when possible...
    Generally good advice.

    >it's usually better to return 0 than to return EXIT_SUCCESS...
    I would love to hear why you think this. There's no valid reason to use one over the other, so clearly it's a stylistic issue. But I'd still be interested in seeing your reasoning.

    >if you use a system command, people can easily make your code do bad things.
    Not if the command is a string literal. It's just that system is godawful slow and takes up a considerable amount of resources compared to other methods.

    >you also don't need the main() at the end of the void functions
    Partly because calling main recursively is bad style and mostly because calling main recursively is illegal in C++.

  9. #9
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    >it's usually better to return 0 than to return EXIT_SUCCESS...
    I would love to hear why you think this. There's no valid reason to use one over the other, so clearly it's a stylistic issue. But I'd still be interested in seeing your reasoning.
    I've never seen EXIT_SUCCESS used and it serves no purpose other than to confuse other programmers, take up more memory for your code, and make you look pretentious. So don't waste your time typing it instead of 0.

    >if you use a system command, people can easily make your code do bad things.
    Not if the command is a string literal. It's just that system is godawful slow and takes up a considerable amount of resources compared to other methods.
    ESPECIALLY if the command is a string literal. I don't know how often we tell people not to use system. It's not portable. Other OSs don't have a program in the default directory called pause. That's what system does - it actually executes the OS command that you put in parentheses, so if you don't have a pause program, you've got a problem. Someone can write a pause program, make it do something else, and then you still have a problem.

    >you also don't need the main() at the end of the void functions
    Partly because calling main recursively is bad style and mostly because calling main recursively is illegal in C++.
    ... and it's going to chew up resources and actually alter program flow. USE QUOTE TAGS!

  10. #10
    Compulsive Liar Robc's Avatar
    Join Date
    Jul 2004
    Posts
    149
    I've never seen EXIT_SUCCESS used and it serves no purpose other than to confuse other programmers, take up more memory for your code, and make you look pretentious.
    Have you ever seen EXIT_FAILURE? If not then the code you've been reading probably isn't portable. EXIT_SUCCESS is pretty obvious IMO as I can't begin to imagine how
    Code:
    return EXIT_SUCCESS;
    or
    Code:
    exit(EXIT_SUCCESS);
    could possibly be misinterpreted while the equivalent 0 would potentially be confusing if a reader didn't remember that 0 means success when terminating a program. The only confusing part would be the necessity of including <cstdlib>, but remembering that is no harder than remembering to include any other header for standard library use.

    As for taking up space, yes it does take more keystrokes and result in an infintesimally larger source file, but the preprocessed file will probably end up with 0 anyway, and the effect on the executable will be nil. This cost is well worth it when you consider the added transparency of the source. Don't forget that we write code for more than just the compiler to read.

    >It's not portable.
    I don't know how I forgot to mention that, thanks. But I wasn't arguing in favor of using system, just in case you misinterpreted my comments.

    >... and it's going to chew up resources and actually alter program flow.
    If you mean the resources needed to throw a compiler error, yes. Calling main recursively is illegal in C++, the code won't compile if the compiler conforms properly to the standard.

  11. #11
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    Maybe so - but would you hire a programmer that didn't consider return 0 second nature? And does anyone know if cstdlib is going to cause the need for the compiler to link in a library you wouldn't have anyway? I didn't like that part of my Borland compiler so I'm afraid I never learnt enough about it to have this conversation... heh heh...

    just in case you misinterpreted my comments.
    Oh Ok. Well then just to re-echo what's his name - yes definately move away from system() calls. Another alternative is Sleep(1000) <-- where 1000 is the number of milliseconds. This call is to pause 1 second. It's in windows.h I believe.

    And regarding the calls to main: Ahh - good point. My bad. But just so chix/w/guns understand the principle, since you can do the same thing by a function calling itself in a loop. It takes memory to have a function running. So if you function calls itself and gets in a loop that lasts more than a few iterations, you're very quickly going to have low resources.

  12. #12
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    Uhh... Whether it uses EXIT_SUCCESS or 0 does not affect portability, nor does using EXIT_FAILURE. By convention, 0 means success. Numerous programs have their own return codes to indicate different types of failures. And, it is not terribly difficult to remember that 0 means success.

  13. #13
    Compulsive Liar Robc's Avatar
    Join Date
    Jul 2004
    Posts
    149
    >but would you hire a programmer that didn't consider return 0 second nature?
    It depends on how they learned and how much experience they have. Standard C++ doesn't require main to return a value, defaulting to 0 when execution falls off the end. For programmers that spent a fraction of their time with main using standard C++ who then moved on to libraries and sections of code that don't use main, I can fully understand thinking of 0 as a failure code, and that can cause problems.

    But yes, I would be a little wary if they saw
    Code:
    return 0;
    and said "What does that mean?" In the end, it's a matter of style. I find both to be equally descriptive, but whenever I make use of EXIT_FAILURE, I use EXIT_SUCCESS for symmetry. Otherwise I opt for either 0 or no return statement at all depending on how lazy or pedantic I'm feeling at the time.

    >And does anyone know if cstdlib is going to cause the need for the compiler to link in a library you wouldn't have anyway?
    <cstdlib> is a standard header. As long as you don't use any non-portable extensions, you can include it and use its contents in any C++ program.

    >so I'm afraid I never learnt enough about it to have this conversation... heh heh...
    I guess that negates my heinous blunder in forgetting to mention that the argument to system was non-portable and pointing out how that could be a security issue. It would have saved me from a bad reputation marker and an embarrasing correction.

    >Another alternative is Sleep(1000)
    That wouldn't work too well for pausing the program before termination. One second isn't usually long enough for the user to read and process the output. You could make it several seconds, but users are big about control and like to stop the program whenever they feel godly. So something that breaks on user input is a good choice.

    >It's in windows.h I believe.
    Yes.

    >gets in a loop that lasts more than a few iterations, you're very quickly going to have low resources.
    How few "a few" is depends on the memory allocated to your process and remaining "stack" space for the activation records. Modern systems can have surprisingly deep recursive paths if the stack frame is relatively small. But recursion should be used judiciously despite that.

  14. #14
    Registered User
    Join Date
    Feb 2004
    Posts
    35
    Quote Originally Posted by Robc
    It depends on how they learned and how much experience they have. Standard C++ doesn't require main to return a value, defaulting to 0 when execution falls off the end. For programmers that spent a fraction of their time with main using standard C++ who then moved on to libraries and sections of code that don't use main, I can fully understand thinking of 0 as a failure code, and that can cause problems.
    On the other hand though, EXIT_SUCESS and EXIT_FALIURE doesn't say anything about what type of variable and what value it has, nor does it help any that they are declared elsewhere. Combine that with exit() instead of return, and you got yourself a real newbie confuser.

  15. #15
    Compulsive Liar Robc's Avatar
    Join Date
    Jul 2004
    Posts
    149
    >Combine that with exit() instead of return, and you got yourself a real newbie confuser.
    Heheh, fair enough. Thought it might be said that abstraction is a good thing for beginners. One could simply be told to define main as returning int and that EXIT_SUCCESS will work, without explaining why until a more suitable time. But to save myself from a mini holy war (sheer selfishness, I assure you), I'll say again that I feel it's a stylistic issue and leave it at that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Numerical order with ifs question?
    By JDrake in forum C++ Programming
    Replies: 5
    Last Post: 11-04-2006, 01:29 PM
  2. Order of operations question
    By nicomp in forum C++ Programming
    Replies: 9
    Last Post: 09-20-2006, 07:18 PM
  3. Exam Question - Possible Mistake?
    By Richie T in forum C++ Programming
    Replies: 15
    Last Post: 05-08-2006, 03:44 PM
  4. Very simple question, problem in my Code.
    By Vber in forum C Programming
    Replies: 7
    Last Post: 11-16-2002, 03:57 PM
  5. Question involving using math operations...
    By Screwz Luse in forum C Programming
    Replies: 6
    Last Post: 12-04-2001, 05:20 PM