Day 09: Function Methods Procedures A method (also called a "subprogram") is a group of instructions that has been given a name and can be "called" (executed) as needed. A method that does not return anything is sometimes called a procedure or a void method. Procedures have two very useful purposes in writing programs: 1. They provide a way to organize program code by dividing it into modules. 2. They provide a way to re-use code. We have been "writing" procedures since day 1: Initialize, LoadContent, Update, Draw are all procedures. XNA has provided the procedure shells for us and we have been filling in the code. Procedures are invoked by writing the name of the procedure. Example DoSomething(); To create a new procedure: void <procedureName> (<argumentList>) { // procedure body } Explanation The keyword void means that the procedure does not return a value. The procedure name can be anything that follows the naming rules of C#. Capitalize each word of the procedure name. The argument list is a list of values that you want to send to the procedure. The list can be empty. You can put any C# statements that you want in between the curly brackets. Example: Write this procedure. This procedure prints the message "Hello" in the Output window. Note that there is one difference between writing a procedure in a Console application and in an XNA application. You must put the keyword static in front of the word void in a Console procedure: static void DisplayGreeting() { Console.WriteLine("Hello"); } Add code to call the procedure in the program's Main procedure: DisplayGreeting(); 2/9/2016 Document1 Page 1 of 10 Function Methods A function is a method that returns a value. I will use the word function to refer to a method that returns a value and I will use the term "procedure" to refer to a method that does not return a value. All methods are invoked by simply typing their name, followed by a pair of parentheses. We have already used methods a great deal. Every program we have written has had the following procedure methods: Initialize LoadContent UnloadContent Update Draw Why are these procedures? Because they don't return a value. How do we know? Because the method name is preceded by the word void. This keyword means that the method does not return a value. Built-in functions Example We have already used built-in functions. Consider the following code snippet: kbd = Keyboard.GetState(); This is a call to the GetState function of the Keyboard object. What does GetState return? It returns a structure of type KeyboardState. This is how the kbd variable gets assigned a value; it gets assigned the value that is returned by the GetState function. A function is invoked, or called, by writing the function name followed by a list of arguments. Example Here is another built-in function that we have used: if (kbd.IsKeyDown(Keys.Escape)) this.Exit(); The Boolean expression of the if statement is a call to the IsKeyDown function of the kbd object. When we call the IsKeyDown function, we need to tell it which key to look at. That's what the Keys.Escape value is. It is information that we are "passing" to the function to allow it to do its job. The Keys.Escape value is called an argument or parameter and represents information that we are "passing" (sending) to the function so that it can do its job. A function is usually called at a place in a program where it is appropriate to use a value of the type that is returned by the function. That is, a function like IsKeyDown that returns a Boolean value can be used anywhere in a program where it is appropriate for a Boolean 2/9/2016 Document1 Page 2 of 10 value to appear (usually in an if statement). An int function (function that returns an int) can be used anywhere in a program where an integer can be used. A string function can be used anywhere in a program where it is appropriate to use a string, etc. Examples Here are some functions that we have already used: Math.Sqrt(n) ToString() //returns a double: the square root of n //returns a string The String class also has built-in functions called member functions that are invoked by giving the name of the string followed by a dot, followed by the name of the function: s.Trim() //returns a string: s with leading/trailing blanks removed s.ToUpper() //returns a string: s in upper case s.ToLower() //returns a string: s in lower case s.Substring(start, len) //returns a string: the specified substring of s All about functions A function is actually a set of instructions that has been given a name and assigned a return type (e.g. int or string). Whenever we use the name of the function in our program (this is known as "calling" the function), the computer locates the set of instructions that has been given this name, and goes and executes those instructions. If information needs to be passed to the function (these values are called arguments) they are listed in parentheses and their values (copies) are made available to the function. When the function has computed the value it is supposed to compute, it returns that single value to the calling location. A function can be called anywhere in a program where it is legal to use the type returned by the function. For example, a Boolean function can be called in the conditional part of an if statement. An int function can be used anywhere in a program where it is appropriate to use an int. Arguments Argument: a value sent to a function. Arguments are listed in parentheses immediately after the name of the function. In the case of the string member functions, the argument that we are "sending" is the string object itself (and a string is returned). In the case of the Substring function, we are sending the object itself AND two arguments (the numbers in parentheses), and a string is getting returned. In the case of the Math functions, we are sending a number (or numbers). 2/9/2016 Document1 Page 3 of 10 Calling a function When calling a function, in addition to knowing the name of the function, you must: Send the correct number of arguments, Send the arguments in the correct order, Make sure that the types of the arguments are the same type that the function is expecting Example You must send the correct number of arguments. Assume that the following instruction has been executed: string name = "George Washington"; You can get the first name by doing this: string firstName = name.Substring(0, 6); In this case, the Substring function expects that you send a pair of integers representing the (zero-based) starting position and the number of characters that you want. If you try this: firstName = name.Substring(0, 6, 10); you will get a syntax error because the Substring function is expecting only two integers, the starting position and the number of characters, and it doesn't know what to do with the third argument. Example You must send the arguments in the correct order. If you want the first 6 characters of a string, you must do this: firstName = name.Substring(0, 6); If you try this: firstName = name.Substring(6, 0); you will get an empty string (the string starting at location 6 that is zero characters long). Example The argument types must be the same types that the function is expecting. If you want the first 6 characters of a string, you must do this: firstName = name.Substring(0, 6); If you try this: firstName = name.Substring(0, 6.5); you will get an error because the Substring function is expecting two integers and you are sending an int and a double. 2/9/2016 Document1 Page 4 of 10 Example Create a C# console project and name it Functions01. A string function may be called anywhere a string can be used in a program. In this example, we are calling the ToUpper member function (it is a "member" of the string class). The ToUpper function returns the value "GEORGE WASHINGTON" but does NOT change the value of the object (the variable theName). string theName = "George Washington"; Console.WriteLine("Upper case: " + theName.ToUpper()); Console.WriteLine("Original string: " + theName); We can also change the value of a variable. Note that the object (theName) is NOT changed in a function call. If we want to change the argument, we must put it on the left side of an assignment statement, like this: theName = theName.ToUpper(); Console.WriteLine("Original string: " + theName); We can also leave the object unchanged, but assign the value returned from the function in another variable: string capsName = theName.ToUpper(); Console.WriteLine(theName); Console.WriteLine(capsName); Example In this example, we are calling the Substring member function (it is a "member" of the string class). Since the Substring function also needs to know (1) where to start in the string, and (2) how many characters to pick off, we also need to send 2 integer arguments, in this case the numbers 0 and 6. Note that when you send multiple arguments to a function, the order of the arguments is important! theName = "George Washington"; string firstName = theName.Substring(0, 6); Console.WriteLine("Original string: " + theName); Console.WriteLine("First Name: " + firstName); Example Functions may also return numeric values. The Math class has a number of functions that return numbers. One such function is the Abs (absolute value) function: int n = -10; int m; m = Math.Abs(n); Console.WriteLine("Absolute value of {0} is {1}", n, m); A function that returns a number may be used any place in a program where it is legal to use a number of that type. Example double x; 2/9/2016 Document1 Page 5 of 10 Console.Write("Enter a number: "); x = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("Absolute value: {0}", Math.Abs(x).ToString()); Console.WriteLine("Square root: {0}", Math.Sqrt(x).ToString()); Writing your own functions C# also allows us to write our own functions. One advantage of writing our own functions is that we can re-use them without having to re-write the code. Syntax <return type> <function name> (<arguments>) { <statements> return <value to return>; } Example Write a function to accept an integer and return twice its value. //Can't call it "double"! Double is a reserved word! static int TimesTwo(int n) { return 2 * n; } Example Write a function to determine the cube of an integer. static int Cube(int n) { return n * n * n; } Example Write a function to compute the area of a rectangle when given its length and width (ints). static int RectangleArea(int length, int width) { return length * width; } Example Write a function to compute the perimeter of a rectangle when given the length and width (doubles). static double RectanglePerimeter(double length, double width) { return length * 2 + width * 2; } 2/9/2016 Document1 Page 6 of 10 Can this function be called with integers as arguments??? Example Write a function to compute the area of a circle when given its radius (a double). static double CircleArea(double radius) { return 3.14159 * radius * radius; // Instead of 3.14159, you can use Math.PI } Example Write a function to compute the circumference of a circle when given its radius (a double). static double CircleCircumference(double radius) { return Math.PI * radius * 2; } Example Write a function to determine an employee's pay when given his hours worked and hourly rate of pay. Assume that the employee earns time-and-a-half for overtime. That is, he earns 1.5 times his usual rate of pay for all hours over 40. static double Pay(double hours, double rate) { if (hours <= 40) return (hours * rate); else return (40 * rate) + (hours-40)*rate*1.5; } Example You can also write Boolean functions: static bool IsEven(int n) { if (n % 2 == 0) return true; else return false; } Note that this can also be written like this: static bool IsEven(int n) { return (n % 2 == 0); } We could also write an IsOdd function: 2/9/2016 Document1 Page 7 of 10 static bool IsOdd(int n) { return (n % 2 != 0); } A function can use a switch statement: static String LetterGrade(int points) { switch(points) { case 0: return "F"; case 1: return "D"; case 2: return "C"; case 3: return "B"; case 4: return "A"; default: return "X"; } 2/9/2016 Document1 Page 8 of 10 Functions Practice Do the following: (1) Miles Per Hour. Ask the user for miles and hours. Then call the MilesPerHour function. The "input" (arguments supplied) to the function: (1) miles (double), (2) hours (double). The "output" (value returned) from the function is the miles per hour (double). The milesPerHour function should divide miles by hours and return the result. Display the result with a single digit to the right of the decimal point. (2) Inches to Centimeters. Ask the user for the number of inches. Then call the inchesToCentimeters function. The "input" (arguments supplied) to the function: (1) inches (double). The "output" (value returned) from the function should be the number of centimeters (double). The function should multiply the argument by 2.54 and return the result (double). Display the result with two digits to the right of the decimal point. (3) Golf Handicap. Ask the user for his average score and par. Then call the GolfHandicap function. The "input" (arguments supplied) to the function: (1) average (an integer), (2) par (an integer). The "output" (value returned) from the function is the handicap (an integer). The function should subtract Par from the Average and take three-fourths of this value (truncate any fraction) and return it. Display the result as an integer. (4) Test Average. Ask the user for a mid-term test score and a final test score. Then call the TestAverage function. The "input" (arguments supplied) to the function: (1) mid-term test score (an integer), (2) final test score (an integer). The "output" (value returned) from the function should be the average (double). The function should determine the average of the two numbers and return the result. Display the result with a single digit to the right of the decimal point. (5) Loan Payment. Ask the user for the principal (double), annual rate (double), and number of years (an integer). Assume that users will enter the rate as a whole number (that is, they will enter 7% as 7 rather than .07). This means that you must divide the rate by 100 to get the correct annual interest rate. Then call the LoanPayment function. The "input" (arguments supplied) to the function: (1) principal, (2) annual interest rate, (3) years. The "output" (value returned) from the function is the monthly payment (a double). The LoanPayment function must calculate and return the regular payment using the following formula: Principal * (RatePerPeriod) ------------------------------------------------------1 – (1 + RatePerPeriod) ^(-Periods) Note: The function must divide annual rate by 12 to get the interest rate per period. Multiply the years by 12 to get the number of payment periods. Display your answer with a dollar sign and two digits to the right of the decimal point. To raise a number to a power in C#, use the Math.Pow function. A program shell is provided below. All you have to do is write the functions. 2/9/2016 Document1 Page 9 of 10 static void Main(string[] args) { double miles, hours; Console.Write("How many miles?"); miles = Convert.ToDouble(Console.ReadLine()); Console.Write("How many hours?"); hours = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("MPH is: {0:F1}" + MilesPerHour(miles, hours)); double inches; Console.Write("How many inches?"); inches = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("{0:F1} inches is {1:F1} cm", inches, InchesToCentimeters(inches)); int golfAverage, par; Console.Write("What is your golf average for 18 holes?"); golfAverage = Convert.ToInt32(Console.ReadLine()); Console.Write("What is par?"); par = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Your handicap is {0}.", GolfHandicap(golfAverage, par)); int midTerm, final; Console.Write("What was your mid-term test score?"); midTerm = Convert.ToInt32(Console.ReadLine()); Console.Write("What was your final test score?"); final = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Your term average is {0:F2}", TestAverage(midTerm, final)); double principal, annualRate; int years; Console.Write("What is the principal?"); principal = Convert.ToDouble(Console.ReadLine()); Console.Write("What is the annual rate?"); annualRate = Convert.ToDouble(Console.ReadLine()); Console.Write("How many years?"); years = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Your monthly payment is {0:C2}.", LoanPayment(principal, annualRate, years)); Console.ReadLine(); } 2/9/2016 Document1 Page 10 of 10