Parameters and return
Problem
One receipt, different totals
You want a method that prints the last line of the receipt: "Total: €…". But the total is different for every order.
The methods from the last lesson always print the same thing. A method PrintTotal() has no way to know the total. You do not want a separate method for every total either. You need a way to pass the total to the method when you call it.
The idea
Parameters: what the method gets
In the parentheses, declare what the method expects: a type and a name. That is a parameter. Inside the method it is an ordinary variable.
When you call it, you put the value in the parentheses. That value is called an argument.
static void PrintTotal(double total){ Console.WriteLine("Total: €" + total);}
PrintTotal(12.5);PrintTotal(4.2);Total: €12.5Total: €4.2double total is the parameter. 12.5 and 4.2 are the arguments. There is one method, and it prints different totals.
If there are several parameters, you separate them with commas. The arguments are passed in the same order.
Try it
By position, not by name
What will the program print?
static void PrintLine(string item, int qty){ Console.WriteLine(item + ": " + qty + " pcs");}
string coffee = "Coffee";int qty = 3;PrintLine(coffee, 2);Arguments are matched to parameters by position: the first one to item, the second one to qty. The variable qty outside has nothing to do with the parameter qty, even though they have the same name.
Problem
Why did the price not go down?
You have written a method for a 10% discount and called it:
static void ApplyDiscount(double price){ price = price * 0.9;}
double price = 100;ApplyDiscount(price);Console.WriteLine(price); // 100100The price is still 100. The method gives no error, and yet the discount is not there. Where did it go?
See it
The method gets a copy
static void ApplyDiscount(double price){ price = price * 0.9;}
double price = 100;ApplyDiscount(price);Console.WriteLine(price); // 100Step by step, in words
- In Main there is a variable price = 100.
- You call ApplyDiscount(price): new memory is set aside for the method.
- The value is copied into its parameter price.
- The method lowers its copy: 100 * 0.9 = 90.
- The method ends and its memory goes away, along with the copy.
- And price in Main is still 100.
When you call it, the method does not get the variable price itself, but a copy of its value. It lowers the copy. When the method ends, its memory goes away, and the copy goes with it. This is called pass by value.
The two variables have the same name (price) on purpose: that is exactly what confuses people in practice. The name does not matter. Every method has its own variables.
The idea
return: the method returns a result
The fix is for the method to return the new price. Before the name, instead of void, you write the type of the result (double), and in the body you write return and the value.
static double ApplyDiscount(double price){ return price * 0.9;}
double price = 100;price = ApplyDiscount(price);Console.WriteLine(price); // 90Step by step, in words
- In Main: price = 100.
- You call ApplyDiscount(price): memory is set aside for the method.
- The value is copied into the parameter price.
- return price * 0.9: the result is 90.
- The result goes back to Main and is stored in price.
- Now price in Main is 90.
The call ApplyDiscount(price) is now a value. You can store it in a variable (as here), print it or calculate with it.
More precisely, if you are curious
- In a
voidmethod you can also writereturn;(with no value). It just ends the method.
- C# also has a way for a method to change the caller's variable itself:
ref. Without, a method returns a value through a parameter, sometimes several at once. You write both in the declaration and in the call:
static void UpdateValue(ref int value){ value += 5;}
static void GetLimits(out int min, out int max){ min = 1; max = 10;}
int number = 10;UpdateValue(ref number);Console.WriteLine(number);
GetLimits(out int a, out int b);Console.WriteLine(a + " " + b);151 10Use them rarely. A method that returns its result with return is easier to read.
Try it
What is the result?
The method works out a 20% VAT on the price. What type should go in the blank?
static Vat(double price)
{
return price * 0.2;
}price * 0.2 is a decimal number, so the result is double.Try it
Returned, but lost
What will the program print?
static int Reserve(int seats){ seats = seats - 2; Console.WriteLine("inside: " + seats); return seats;}
int seats = 10;Reserve(seats);Console.WriteLine("outside: " + seats);The method changes its copy and returns 8, but nobody stores the result. To keep it, you need seats = Reserve(seats);.
The idea
return ends the method
The shop does not charge for delivery on orders of €50 or more. Otherwise delivery is €4.99:
static double ShippingCost(double total){ if (total >= 50) { return 0; } return 4.99;}
Console.WriteLine(ShippingCost(62.0));Console.WriteLine(ShippingCost(18.5));04.99As soon as it reaches return, the method ends right away. That is why at €62 the second return does not run, and we do not need an else.
A method with a result has to return a value on every path. If you remove the last line, the program does not compile: "not all code paths return a value".
Try it
Find the bug
Club members get a 10% discount, and everyone else pays the full price. But everyone gets the discount. Which line is the bug on?
Pick the line with the bug.
The last return is for people who are not members: they pay the full price, return price;.
Exercise
Methods that calculate
Solve the tasks in your editor. Each method gets what it needs as parameters and returns the result. The printing happens in Main.
1. Average. The method Average(int[] values) returns the average of the numbers in the array. In Main, read from the keyboard how many numbers there are, then the numbers themselves.
51015202530Average: 202. Prime number. The method IsPrime(int n) returns whether the number is prime (divisible only by 1 and by itself). For 7 it returns True, for 12 False.
3. Temperatures. The methods ToFahrenheit(double c) and ToCelsius(double f). F = C · 9 / 5 + 32. Read a temperature and a unit (C or F) and print the converted one.
100C100 C = 212 F4. Calculator. The method Calculate(double a, double b, char op) returns the result for +, -, * or /. The operation is chosen with if.
105+10 + 5 = 155. A triangle with a parameter. We promised it in the last lesson. The method PrintTriangle(int height) prints a right triangle of asterisks with height height. For 3:
** ** * *More precisely, if you are curious
Watch out for 5 / 9 in the Celsius formula. Both numbers are whole numbers, so the division is integer division and the result is 0. Write (f - 32) * 5 / 9: then f - 32 is a double and the whole calculation is done with decimals.
Exercise
Methods for arrays
Each task is one method that gets an array (or a word) and returns a result. At the end, put them all together in one program.
Sum,SumEvenandSumOdd: the sum of all the numbers, of the even ones and of the odd ones in the array.Reverse: returns a new array with the numbers in reverse order.MaxandMin: the largest and the smallest number.IsPalindrome(string word): whether the word reads the same forward and backward.SumDiagonalsandSumDiagonalsOnce: the sum along both diagonals of a square matrix, with the center element counted twice and once.- All together: for the array
{ 1, 2, 3, 4, 5 }, the number 7 (withIsPrimefrom the card above), the words "level" and "ABCDE" and the 3 × 3 matrix with the numbers from 1 to 9.
Sum: 15, Even: 6, Odd: 9Reversed: [5, 4, 3, 2, 1]Max: 5, Min: 17 is prime: Truelevel: True, ABCDE: FalseSum with repeats: 30, Sum without repeats: 25Test