1 / 52

C++ Programming I Lecture 5

C++ Programming I Lecture 5. MIS160 Instructor – Larry Langellier. Lecture 5 - Functions. Outline 3.10 Storage Classes 3.11 Scope Rules 3.12 Recursion 3.13 Example Using Recursion: The Fibonacci Series 3.14 Recursion vs. Iteration 3.15 Functions with Empty Parameter Lists

Download Presentation

C++ Programming I Lecture 5

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C++ Programming I Lecture 5 MIS160 Instructor – Larry Langellier

  2. Lecture 5 - Functions Outline 3.10 Storage Classes 3.11 Scope Rules 3.12 Recursion 3.13 Example Using Recursion: The Fibonacci Series 3.14 Recursion vs. Iteration 3.15 Functions with Empty Parameter Lists 3.16 Inline Functions3.17 References and Reference Parameters3.18 Default Arguments 3.19 Unary Scope Resolution Operator3.20 Function Overloading 3.21 Function Templates

  3. Storage Classes • Storage class specifiers • Storage class • Where object exists in memory • Scope • Where object is referenced in program • Linkage • Where an identifier is known • Automatic storage • Object created and destroyed within its block • auto • Default for local variables. • Example: auto float x, y; • register • Tries to put variables into high-speed registers • Can only be used with local variables and parameters

  4. Storage Classes • Static storage • Variables exist for entire program execution • static • Local variables defined in functions • Keep value after function ends • Only known in their own function • Extern • Default for global variables and functions. • Known in any function

  5. Variables and Storage Classes • The storage class of a variable determines • Which parts of a program can access it • How long it stays in existence • We’ll look at these three storage classes • Automatic • External • Static

  6. Automatic Variables • Automatic Variables are ones whose definition occurs inside the braces that delimit the function body – this includes the main( ) function • The variables we’ve defined in this course so far have been automatic variables • Lifetime • Not created until the function it’s defined in is called • Destroyed when the function returns and control is passed back to the calling program

  7. Automatic Variables • Visibility – aka Scope • The locations within a program where the variable can be accessed • Automatic variables are only visible (accessible) in the function where they are defined • Limiting the visibility of a variable help organize and modularize • Sometimes called Local Variables

  8. External Variables • Defined outside of (external to) any function • An external variable is visible to all functions that follow the variable’s definition • Since you usually want the variable visible to all functions the declarations should be at the top • Also known as Global Variables • External Variables exist for the entire life of the program • Example – extern.cpp • External variables are automatically initialized to 0, unlike Automatic variables which are not initialized

  9. Static Variable (Automatic) • A static automatic variable has the visibility (scope) of a local (automatic) variable, but it’s lifetime is similar to an external • The difference in lifetime between a static and external variable is that the static comes into existence when the function is first called • Used when it’s necessary for a function to remember a value from one call to the next • Example – static.cpp • Initialization occurs with the declaration of the variable and only executes the first time the function is called

  10. Identifier Scope Rules • File scope • Defined outside a function, known in all functions • Examples include, global variables, function definitions and functions prototypes • Function scope • Can only be referenced inside a function body • Only labels (start:, case:, etc.) • Block scope • Declared inside a block. Begins at declaration, ends at } • Variables, function parameters (local variables of function) • Outer blocks “hidden” from inner blocks if same variable name • Function prototype scope • Identifiers in parameter list • Names in function prototype optional, and can be used anywhere

  11. 1 // Fig. 3.12: fig03_12.cpp 2 // A scoping example 3 #include <iostream> 4 x is different inside and outside the block. 5 using std::cout; 6 using std::endl; 7 8 void a( void ); // function prototype 9 void b( void ); // function prototype 10 void c( void ); // function prototype local x in outer scope of main is 5 local x in inner scope of main is 7 local x in outer scope of main is 5 11 12 int x = 1; // global variable 13 14 int main() 15 { 16 int x = 5; // local variable to main 17 18 cout << "local x in outer scope of main is " << x << endl; 19 20 { // start new scope 21 int x = 7; 22 23 cout << "local x in inner scope of main is " << x << endl; 24 } // end new scope 25 26 cout << "local x in outer scope of main is " << x << endl; 27 28 a(); // a has automatic local x 29 b(); // b has static local x 30 c(); // c uses global x 31 a(); // a reinitializes automatic local x 32 b(); // static local x retains its previous value 33 c(); // global x also retains its value 34 1. Function prototypes 1.1 Initialize global variable 1.2 Initialize local variable 1.3 Initialize local variable in block 2. Call functions 3. Output results

  12. 35 cout << "local x in main is " << x << endl; 36 37 return 0; Local automatic variables are created and destroyed each time a is called. 38 } local x in a is 25 after entering a local x in a is 26 before exiting a 39 Local static variables are not destroyed when the function ends. 40 void a( void ) 41 { 42 int x = 25; // initialized each time a is called local static x is 50 on entering b local static x is 51 on exiting b 43 Global variables are always accessible. Function creferences the globalx. 44 cout << endl << "local x in a is " << x 45 << " after entering a" << endl; global x is 1 on entering c global x is 10 on exiting c 46 ++x; 47 cout << "local x in a is " << x 48 << " before exiting a" << endl; 49 } 50 51 void b( void ) 52 { 53 static int x = 50; // Static initialization only 54 // first time b is called. 55 cout << endl << "local static x is " << x 56 << " on entering b" << endl; 57 ++x; 58 cout << "local static x is " << x 59 << " on exiting b" << endl; 60 } 61 62 void c( void ) 63 { 64 cout << endl << "global x is " << x 65 << " on entering c" << endl; 66 x *= 10; 67 cout << "global x is " << x << " on exiting c" << endl; 68 } 3.1 Define Functions

  13. local x in outer scope of main is 5 local x in inner scope of main is 7 local x in outer scope of main is 5 local x in a is 25 after entering a local x in a is 26 before exiting a local static x is 50 on entering b local static x is 51 on exiting b global x is 1 on entering c global x is 10 on exiting c local x in a is 25 after entering a local x in a is 26 before exiting a local static x is 51 on entering b local static x is 52 on exiting b global x is 10 on entering c global x is 100 on exiting c local x in main is 5 Program Output

  14. Just Do It! Write a function, that when you call it, displays a message telling how many times it has been called: “I have been called 3 times”, or whatever. Write a main()program that calls this function at least 10 times. First, use an external variable to store the count. Second, use a local static variable. Which is more appropriate? Why can’t you use an automatic variable?

  15. Sample Solution // selfcnt.cpp // function tells how many times it has been called #include <iostream> using std cout; using std cin; using std endl; int selfcnt(); //declaration // int count = 0; //remove comment to use external //-------------------------------------------------------------- int main() { for(int j=0; j<10; j++) { cout << "\nselfcnt() has been called " << selfcnt() << " times"; } cout << endl; return 0; } //-------------------------------------------------------------- int selfcnt() { static int count = 0; //comment out to use external return ++count; }

  16. Functions with Empty Parameter Lists • Empty parameter lists • Either writing voidor leaving a parameter list empty indicates that the function takes no arguments void print(); or void print( void ); • Function print takes no arguments and returns no value

  17. 1 // Fig. 3.18: fig03_18.cpp 2 // Functions that take no arguments Notice the two ways of declaring no arguments. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 void function1(); 9 void function2( void ); 10 11 int main() 12 { 13 function1(); 14 function2(); 15 16 return 0; 17 } 18 19 void function1() 20 { 21 cout << "function1 takes no arguments" << endl; 22 } 23 24 void function2( void ) 25 { 26 cout << "function2 also takes no arguments" << endl; 27 } 1. Function prototypes (take no arguments) 2. Call the functions Function definitions Program Output function1 takes no arguments function2 also takes no arguments

  18. Inline Functions • inline functions • Reduce function-call overhead • Asks the compiler to copy code into program instead of using a function call • Compiler can ignore inline • Should be used with small, often-used functions • Example: inline double cube( const double s ) { return s * s * s; }

  19. Reference Arguments • Passing “by reference” changes all of that • Instead of passing a value, a “reference” to the original variable in the calling program is passed • This allows access to the actual variables in the calling program and provides the ability to change them • Also can be used as a mechanism for returning more than one value from the function • Example – ref.cpp

  20. Reference Arguments • The & following the type denotes that an argument is passed by reference void intfrac(float, float&, float&) void intfrac(float n, float& intp, float& fracp) • The ampersand (&) is NOT used in the function call • Example – reforder.cpp

  21. References and Reference Parameters • Call by value • Copy of data passed to function • Changes to copy do not change original • Used to prevent unwanted side effects • Call by reference • Function can directly access data • Changes affect original • Reference parameter alias for argument • & is used to signify a reference void change( int &variable ) { variable += 3; } • Adds 3 to the variable inputted int y = &x. • A change to y will now affect x as well

  22. 1 // Fig. 3.20: fig03_20.cpp 2 // Comparing call-by-value and call-by-reference Notice the use of the & operator 3 // with references. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 int squareByValue( int ); 10 void squareByReference( int & ); 11 12 int main() 13 { 14 int x = 2, z = 4; 15 16 cout << "x = " << x << " before squareByValue\n" 17 << "Value returned by squareByValue: " 18 << squareByValue( x ) << endl 19 << "x = " << x << " after squareByValue\n" << endl; 20 21 cout << "z = " << z << " before squareByReference" << endl; 22 squareByReference( z ); 23 cout << "z = " << z << " after squareByReference" << endl; 24 25 return 0; 26 } 27 28 int squareByValue( int a ) 29 { 30 return a *= a; // caller's argument not modified 31 } 1. Function prototypes 1.1 Initialize variables 2. Print x 2.1 Call function and print x 2.2 Print z 2.3 Call function and print z 3. Function Definition of squareByValue

  23. 32 33 void squareByReference( int &cRef ) 34 { 35 cRef *= cRef; // caller's argument modified 36 } 3.1 Function Definition of squareByReference Program Output x = 2 before squareByValue Value returned by squareByValue: 4 x = 2 after squareByValue z = 4 before squareByReference z = 16 after squareByReference

  24. Just Do It! Write a function called swap() that interchanges two time ints passed to it by the calling program. This function should swap the values of the variables in the calling program, not just those in the function. You’ll need to decide how to pass the arguments. Create a main() program to exercise the function.

  25. Sample Solution // swapints.cpp // function swaps two structures passed to it #include <iostream> #include <iomanip> //for setw() using std cout; using std cin; using std endl; //------------------------------------------------------- void swap(int& n1, int& n2) //function swaps int values passed by reference { int temp = n1; n1 = n2; n2 = temp; }

  26. Sample Solution (cont.) int main() { //initialize two ints int val_1 = 21, val_2 = 23; cout << "\nBefore swap val_1=" << val_1; cout << ", val_2=" << val_2; swap(val_1, val_2); //call function to swap cout << "\nAfter swap val_1=" << val_1; cout << ", val_2=" << val_2; cout << "\n\n"; return 0; }

  27. const Function Arguments • Passing an argument by reference allows a function to modify a variable in the calling program • If an argument to be passed is large it takes less time to pass it by reference rather than by value, but then the function could change the value of it • What if you have a large argument you want to pass that you don’t want the function to be able to change? Answer: Use a const argument • Example – constarg.cpp Void aFunc(int& alpha, const int& beta);

  28. Default Arguments • If function parameter omitted, gets default value • Can be constants, global variables, or function calls • If not enough parameters specified, rightmost go to their defaults • Set defaults in function prototype int defaultFunction( int x = 1, int y = 2, int z = 3 );

  29. 1 // Fig. 3.23: fig03_23.cpp 2 // Using default arguments 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 int boxVolume( int length = 1, int width = 1, int height = 1 ); 9 10 int main() 11 { 12 cout << "The default box volume is: " << boxVolume() 13 << "\n\nThe volume of a box with length 10,\n" 14 << "width 1 and height 1 is: " << boxVolume( 10 ) 15 << "\n\nThe volume of a box with length 10,\n" 16 << "width 5 and height 1 is: " << boxVolume( 10, 5 ) 17 << "\n\nThe volume of a box with length 10,\n" 18 << "width 5 and height 2 is: " << boxVolume( 10, 5, 2 ) 19 << endl; 20 21 return 0; 22 } 23 24 // Calculate the volume of a box 25 int boxVolume( int length, int width, int height ) 26 { 27 return length * width * height; 28 } 1. Function prototype 2. Print default volume 2.1 Print volume with one parameter 2.2 Print with 2 parameters 2.3 Print with all parameters. 3. Function definition

  30. The default box volume is: 1 The volume of a box with length 10, width 1 and height 1 is: 10 The volume of a box with length 10, width 5 and height 1 is: 50 The volume of a box with length 10, width 5 and height 2 is: 100 Notice how the rightmost values are defaulted. Program Output

  31. Unary Scope Resolution Operator • Unary scope resolution operator (::) • Access global variables if a local variable has same name • not needed if names are different • instead of variable use ::variable

  32. 1 // Fig. 3.24: fig03_24.cpp 2 // Using the unary scope resolution operator 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; Notice the use of :: 7 8 #include <iomanip> 9 10 using std::setprecision; 11 12 const double PI = 3.14159265358979; 13 14 int main() 15 { 16 const float PI = static_cast< float >( ::PI ); 17 18 cout << setprecision( 20 ) 19 << " Local float value of PI = " << PI 20 << "\nGlobal double value of PI = " << ::PI << endl; 21 22 return 0; 23 } 1. Define variables 2. Print variables Program Output Local float value of PI = 3.141592741012573242 Global double value of PI = 3.141592653589790007

  33. Function Overloading • Function overloading • Having functions with same name and different parameters • Should perform similar tasks ( i.e., a function to square ints, and function to square floats). int square( int x) {return x * x;} float square(float x) { return x * x; } • Program chooses function by signature • signature determined by function name and parameter types • Can have the same return types • An overloaded function performs different activities depending on the type of the arguments sent to it • Example – overload.cpp • Also, you can have the same number of arguments where the arguments have different types

  34. 1 // Fig. 3.25: fig03_25.cpp 2 // Using overloaded functions Functions have same name but different parameters 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 int square( int x ) { return x * x; } 9 10 double square( double y ) { return y * y; } 11 12 int main() 13 { 14 cout << "The square of integer 7 is " << square( 7 ) 15 << "\nThe square of double 7.5 is " << square( 7.5 ) 16 << endl; 17 18 return 0; 19 } 1. Define overloaded function 2. Call function Program Output The square of integer 7 is 49 The square of double 7.5 is 56.25

  35. Just Do It! Write a series of overloaded power() functions, that work with types double,int,long, and float. Each function should have two exponents – a base and an exponent – and should raise the base to the exponent power. Write a main()program that exercises these overloaded functions with all argument types.

  36. Sample Solution // powerx.cpp // overloaded function raises number to a power // can use char, int, long, float, or double types #include <iostream> using std cout; using std cin; using std endl; //-------------------------------------------------------------- int power(int n, int p=2); //p has default value 2 long power(long n, int p=2); float power(float n, int p=2); double power(double n, int p=2);

  37. Sample Solution int main() { int intNumber, intAnswer; long lonNumber, lonAnswer; float flNumber, flAnswer; double dbNumber, dbAnswer; intNumber = 25; //type int intAnswer = power(intNumber, 3); cout << "\nintAnswer = " << intAnswer; lonNumber = 50; //type long lonAnswer = power(lonNumber, 3); cout << "\nlonAnswer = " << lonAnswer; flNumber = 123.456F; //type float flAnswer = power(flNumber, 3); cout << "\nflAnswer = " << flAnswer; dbNumber = 123456789123456.0; //type double dbAnswer = power(dbNumber, 3); cout << "\ndbAnswer = " << dbAnswer << endl; return 0; }

  38. Sample Solution //-------------------------------------------------------------- int power( int n, int p ) //type int { int result = 1.0; //start with 1 for(int j=0; j<p; j++) //multiply by n result *= n; //p times return result; } //-------------------------------------------------------------- long power( long n, int p ) //type long { long result = 1.0; //start with 1 for(int j=0; j<p; j++) //multiply by n result *= n; //p times return result; }

  39. Sample Solution //-------------------------------------------------------------- float power( float n, int p ) //type float { float result = 1.0; //start with 1 for(int j=0; j<p; j++) //multiply by n result *= n; //p times return result; } //-------------------------------------------------------------- double power( double n, int p ) //type double { double result = 1.0; //start with 1 for(int j=0; j<p; j++) //multiply by n result *= n; //p times return result; }

  40. Thinking (some more) About Objects • Previous chapter • First phase - identify classes • List nouns, created separate class for each category • Represented classes and relationships in UML class diagram • Classes have • Attributes - data • Focus of this chapter • Example: A radio's attributes include volume level, AM/FM • Operations - functions • Focus of Chapter 4

  41. Class Attributes • Class Attributes • Describe classes • Identify attributes by looking for descriptive words in problem statement • Create an attribute for each descriptive word/phrase • Create attributes to represent data a class may need

  42. Class Attributes (II)

  43. Class Attributes (III) • Notice • Bell and Building have no attributes • As we continue the case study, we will add, modify, and delete information about the classes • Attributes • Name • Type • Initial value • If no initial value, only name and type shown • Example: capacity : int = 1 • For now, not overly concerned with types or initial values • Include information we can get from problem statement

  44. Class Attributes (III) - Class Diagram with Attributes Elevator Clock Door currentFloor : int = 1 time : int = 0 open : bool = false direction : enum = up capacity : int = 1 arrivalTime : int Floor moving : bool = false Bell capacity : int = 1 <none yet> occupied : bool = false Scheduler Light floor1ArrivalTime : int FloorButton floor2ArrivalTime : int on : bool = false pressed : bool = false Person Person ElevatorButton Building ID : int ID : int pressed : bool = false <none yet>

  45. button press Pressed Not pressed button reset Statechart Diagrams • States • Describe condition of an object at a given point in time • Statechart diagrams (state diagrams) • Express how, and under what conditions, objects change state • Format • Rounded rectangle - represents a state • Solid circle with arrowhead - points to initial state • Solid lines with arrows - transitions • Object can transition in response to an event • Name of event written near line

  46. button press [need to move] button press [other floor]/ arrivalTime = currentTime + 5 Servicing Floor when [currentTime == arrivalTime] button press [current floor] Waiting [no further requests] Moving exit/ close door Elevator Statechart Diagram • Guard condition - transition only occurs if condition met • Elevator transitions from "Waiting" state to "Servicing Floor" state when a button is pressed on the elevator's floor • Forward slash / - indicates action with state change

  47. Elevator Statechart Diagram (II) • true condition • State transition if a certain condition is true when [currentTime == arrivalTime] • Elevator transitions from "Moving" state to "Servicing Floor" state • Actions • Model actions by splitting state into Top: state name Bottom: state actions • exit - action label, indicates an action to be performed when an object exits a state • Elevator must "close door" when exits "Servicing Floor" state • If elevator needs to move, it must first close the door

  48. Activity Diagrams • Activity diagram • Variation of statechart diagram • Statechart diagram does not model how the elevator decides if it needs to move • Models what object does during its lifetime (its activities)

  49. Activity Diagrams (II) • Format • Activities modeled as ovals (name inside oval) • Solid line with arrowhead - connects two activities • Indicates order activities are performed • Solid circle - starting point of sequence of activities • In our example, each time button pressed, sequence of activities are executed • Double circle (bull's eye) - ending point of diagram • Diamond - decision • Each line extending from diamond is a different set of activities • Guard condition indicates which path to choose in square brackets [ ] • Activity paths merge at diamond.

  50. button pressed] [ in motion] [ currentTime == current floor button [ [ arrivalTime] not pressed] current floor [ Close door button pressed] Move to other floor Stop moving currentTime < [ arrivalTime] Reset elevator button Ring bell Guard conditions Open door Activity Diagram (III)

More Related