Functions and Data Passing Overview • • • • • • Terminology Why we have functions Data Passing The Mantra Calling Methods Scope of Variables Terminology • A function is a logical grouping of statements • Reusable chunks of code – Write once – Call as many times as you like • Benefits – – – – Reusable Easy to work at higher level of abstraction Reduces complexity Reduces size of code AKA (also known as) • Functions can be called several things, depending on the book or context • Examples: – Procedure – Module – Method (OOP) – Behavior (OOP) – Member function (OOP) You’ve Already Seen Functions Denotes a function of the class Denotes a property of the class Invoking Functions MidiPlayer.Play(new NoteOn(0, GeneralMidiPercussion.BassDrum, 127)); • Two things going on here – Creating a new NoteOn object • Passing it three parameters • “Constructing” (more later) – Invoking the Play method of the MidiPlayer class • Passing it one parameter (the NoteOn object) • This is a “static” method (more later) Why have functions? (see anything similar?) double average; int userNum1, userNum2; Console.WriteLine(“Please enter the 2 numbers”); userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; … // a lot of other code userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; … userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; Why have functions? (see anything similar?) double average; int userNum1, userNum2; Console.WriteLine(“Please enter the 2 numbers”); userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; … // a lot of other code userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; … userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; All of this code is the same! Basic Idea double average; int userNum1, userNum2; Console.WriteLine(“Please enter the 2 numbers”); userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; … // a lot of other code userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; … userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; Basic Idea double average; int userNum1, userNum2; Console.WriteLine(“Please enter the 2 numbers”); userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; … // a lot of other code userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; … userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; Create function instead userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; Give the Function a Name double average; int userNum1, userNum2; Console.WriteLine(“Please enter the 2 numbers”); userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; … // a lot of other code userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; … userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; myFunction userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; Call the Function (instead of writing all that code) double average; int userNum1, userNum2; Console.WriteLine(“Please enter the 2 numbers”); myFunction … // a lot of other code myFunction … myFunction myFunction userNum1 = Int32.Parse(Console.ReadLine()); userNum2 = Int32.Parse(Console.ReadLine()); average = (userNum1 + userNum2) / 2; What have we done? • Written the code once, but called it many times • Reduced the size of our code • Easier to comprehend • This is called procedural abstraction • Tracing of code skips all around (no longer linear) Scope of Variables • Scope – “who can see what” • Variables that are defined within a function can only be seen by that function! • We need a way to send information to the function • We need a way for the function to send back information • Example: function1 can’t see myInt function1 char myChar; function2 int myInt; Example Function Declarations (You’ve seen all of these before) private void buttonAdd_Click(object sender, EventArgs e) private void FormMain_Load(object sender, EventArgs e) private void buttonAddDigit_Click(object sender, EventArgs e) Other Examples private int sum(int x, int y) private string getUserChoice() private void isMatch(int guess) The Mantra • All functions follow a mantra • The mantra is: Return type, function name, parameters Return type, function name, parameters Return type, function name, parameters … … … The return type • A function has the option to return us (the calling method) some information • If the function doesn’t return us any info, the return type is void • Otherwise, the return type is the data type it’s going to return • Example of return types: – int – char – boolean Figure out the return type • Function Name average double or float getLetterGrade char areYouAsleep bool getGPA double or float printMenu void // Don’t confuse what a function does with it’s // return type! getStudentName string The function’s name • Similar to naming of variables • Can be almost anything except – A reserved word (keywords) – Can’t begin with a number – Can’t contain strange symbols except _ and $ • Function names should begin with a lower case – Different standards/conventions are used • If multiple words in function name, capitalize the first letter in each word (except the first) • Example: thisIsAnExample Parameters • Functions cannot see each other’s variables (scope) • Special variables used to “catch” data being passed • This is the only way the main algorithm and functions have to communicate! • Located between parentheses ( ) • If no parameters are needed, leave the parentheses empty Examples • Remember the mantra • What can you tell me about these functions? void doSomething (int data) double average (int num1, int num2) boolean didHePass ( ) char whatWasHisGrade ( ) void scareStudent (char gradeOfStudent) Getting the function to Work for You • Call it by name • Pass it the right stuff – – – – – Pass the right number of parameters If it expects two things, pass it two things! Pass the right type of parameters If it expects a char, don’t pass it a double! Parameters must match exactly • If it returns something, do something with it! Example int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); x y double average (int x, int y) { return ( (x+y) / 2); } // Note: the average function is currently inactive Example (declare variables) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 0 0 0 x y double average (int x, int y) { return ( (x+y) / 2); } // Note: the average function is currently inactive Example (declare variables) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 0 0 0 result1 result2 0.0 0.0 x y double average (int x, int y) { return ( (x+y) / 2); } // Note: the average function is currently inactive Example (set values) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 0 5 0 result1 result2 0.0 0.0 x y double average (int x, int y) { return ( (x+y) / 2); } // Note: the average function is currently inactive Example (set values) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 0 result1 result2 0.0 0.0 x y double average (int x, int y) { return ( (x+y) / 2); } // Note: the average function is currently inactive Example (set values) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 4 result1 result2 0.0 0.0 x y double average (int x, int y) { return ( (x+y) / 2); } // Note: the average function is currently inactive Example (invoke function) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 4 result1 result2 0.0 0.0 WAKE UP! x y double average (int x, int y) { return ( (x+y) / 2); } Example (data passing) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 4 result1 result2 0.0 0.0 x 5 y 7 double average (int x, int y) { return ( (x+y) / 2); } Example (caller sleeps) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 4 result1 result2 0.0 0.0 x 5 y 7 double average (int x, int y) { return ( (x+y) / 2); } // The function is now ACTIVE Example (function active) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 4 result1 result2 0.0 0.0 x 5 y 7 double average (int x, int y) { return ( (x+y) / 2); } // 5 + 7 is 12; 12 / 2 is 6 Example (value returned) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); 6 num1 num2 num3 7 5 4 result1 result2 0.0 0.0 x 5 y 7 double average (int x, int y) { return ( (x+y) / 2); } Example (caller resumes) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 4 result1 result2 6.0 0.0 sleep x y double average (int x, int y) { return ( (x+y) / 2); } Example (call function again) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 4 result1 result2 6.0 0.0 WAKE UP! x y double average (int x, int y) { return ( (x+y) / 2); } Example (data passing) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 4 result1 result2 6.0 0.0 x 4 y 5 double average (int x, int y) { return ( (x+y) / 2); } Example (caller sleeps) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 4 result1 result2 6.0 0.0 x 4 y 5 double average (int x, int y) { return ( (x+y) / 2); } // The function is now ACTIVE Example (function active) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 4 result1 result2 6.0 0.0 x 4 y 5 double average (int x, int y) { return ( (x+y) / 2); } // 4 + 5 is 9; 9 / 2 = 4.5 Example (value returned) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 4 result1 result2 6.0 0.0 4.5 x 4 y 5 double average (int x, int y) { return ( (x+y) / 2); } Example (caller resumes) int num1, num2, num3; double result1, result2; num1 = 5; num2 = 7; num3 = 4; result1 = average (num1, num2); result2 = average (num3, num1); num1 num2 num3 7 5 4 result1 result2 6.0 4.5 sleep x y double average (int x, int y) { return ( (x+y) / 2); } Function Rules • You cannot define a function inside of another function • Functions always reside in a class in C# (as you’ve seen numerous time already) • Functions cannot see each other’s variables • You’ve seen “private static” in our examples… more on this later An Example • Improving the High-Low Game • Add functions to clarify • Rule of thumb – Keep methods/functions small Console High-Low Functions • static private int getUserChoice() • static private bool checkGuess(int guess, int secretNumber) • static private bool playAgain() • static void Main(string[] args)