Параметри и return
Проблем
Една бележка, различни суми
Искаш метод, който печата последния ред на бележката: „Общо: … €“. Но сумата е различна за всяка поръчка.
Методите от миналия урок печатат винаги едно и също. Метод PrintTotal() няма откъде да знае сумата. Не искаш и методи за всяка сума поотделно. Трябва начин да подадеш сумата на метода, когато го викаш.
Идеята
Параметри: какво получава методът
Обяви в скобите какво методът очаква: тип и име. Това е параметър. Вътре в метода той е обикновена променлива.
При извикването слагаш в скобите стойността. Тя се казва аргумент.
static void PrintTotal(double total){ Console.WriteLine("Общо: " + total + " €");}
PrintTotal(12.5);PrintTotal(4.2);Общо: 12.5 €Общо: 4.2 €double total е параметърът. 12.5 и 4.2 са аргументите. Методът е един, а печата различни суми.
Ако параметрите са няколко, разделяш ги със запетая. Аргументите се подават в същия ред.
Пробвай
По място, не по име
Какво ще отпечата програмата?
static void PrintLine(string item, int qty){ Console.WriteLine(item + ": " + qty + " бр.");}
string coffee = "Кафе";int qty = 3;PrintLine(coffee, 2);Аргументите се свързват с параметрите по място: първият с item, вторият с qty. Променливата qty отвън няма нищо общо с параметъра qty, въпреки че се казват еднакво.
Проблем
Защо цената не се намали?
Написал си метод за 10% отстъпка и си го извикал:
static void ApplyDiscount(double price){ price = price * 0.9;}
double price = 100;ApplyDiscount(price);Console.WriteLine(price); // 100100Цената пак е 100. Методът не дава грешка, а отстъпката я няма. Къде отиде?
Виж го
Методът получава копие
static void ApplyDiscount(double price){ price = price * 0.9;}
double price = 100;ApplyDiscount(price);Console.WriteLine(price); // 100Стъпка по стъпка, с думи
- В Main има променлива price = 100.
- Викаш ApplyDiscount(price): за метода се заделя нова памет.
- Стойността се копира в неговия параметър price.
- Методът намалява своето копие: 100 * 0.9 = 90.
- Методът свършва и паметта му изчезва, заедно с копието.
- А price в Main си е 100.
При извикването методът не получава самата променлива price, а копие на стойността ѝ. Той намалява копието. Когато методът свърши, паметта му изчезва, а с нея и копието. Това се казва предаване по стойност.
Двете променливи се казват еднакво (price) нарочно: точно това обърква на практика. Името няма значение, всеки метод има своите променливи.
Идеята
return: методът връща резултат
Поправката е методът да върне новата цена. Пред името вместо void пишеш типа на резултата (double), а в тялото return и стойността.
static double ApplyDiscount(double price){ return price * 0.9;}
double price = 100;price = ApplyDiscount(price);Console.WriteLine(price); // 90Стъпка по стъпка, с думи
- В Main: price = 100.
- Викаш ApplyDiscount(price): заделя се памет за метода.
- Стойността се копира в параметъра price.
- return price * 0.9: резултатът е 90.
- Резултатът се връща в Main и се записва в price.
- Сега price в Main е 90.
Извикването ApplyDiscount(price) вече е стойност. Можеш да я запишеш в променлива (както тук), да я отпечаташ или да смяташ с нея.
По-точно, за любопитните
- В метод с
voidсъщо може да пишешreturn;(без стойност). Той просто приключва метода.
- В C# има и начин методът да промени самата променлива на извикващия:
ref. Сoutметодът връща стойност през параметър, понякога няколко наведнъж. И двете се пишат и при обявата, и при извикването:
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 10Ползвай ги рядко. Метод, който връща резултат с return, се чете по-лесно.
Пробвай
Какъв е резултатът?
Методът смята ДДС от 20% върху цената. Какъв тип трябва да пише на празното място?
static Vat(double price)
{
return price * 0.2;
}price * 0.2 е дробно число, затова резултатът е double.Пробвай
Върнато, но изгубено
Какво ще отпечата програмата?
static int Reserve(int seats){ seats = seats - 2; Console.WriteLine("вътре: " + seats); return seats;}
int seats = 10;Reserve(seats);Console.WriteLine("отвън: " + seats);Методът променя копието си и връща 8, но никой не записва резултата. За да остане, трябва seats = Reserve(seats);.
Идеята
return приключва метода
Магазинът не взима доставка за поръчки от 50 € нагоре. Иначе доставката е 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.99Щом стигне до return, методът свършва веднага. Затова при 62 € вторият return не се изпълнява и не ни трябва else.
Метод с резултат трябва да върне стойност по всеки път. Ако махнеш последния ред, програмата не се компилира: „not all code paths return a value“.
Пробвай
Намери грешката
Членовете на клуба имат 10% отстъпка, останалите плащат пълната цена. Но отстъпка получават всички. На кой ред е грешката?
Избери реда с грешката.
Последният return е за хората, които не са членове: те плащат пълната цена, return price;.
Упражнение
Методи, които смятат
Реши задачите в редактора си. Всеки метод получава каквото му трябва като параметри и връща резултата. Печата се в Main.
1. Средно аритметично. Метод Average(int[] values) връща средното на числата в масива. В Main прочети от клавиатурата колко са числата, после самите числа.
51015202530Средно аритметично: 202. Просто число. Метод IsPrime(int n) връща дали числото е просто (дели се само на 1 и на себе си). За 7 връща True, за 12 False.
3. Температури. Методи ToFahrenheit(double c) и ToCelsius(double f). F = C · 9 / 5 + 32. Прочети температура и мерна единица (C или F) и отпечатай превърнатата.
100C100 C = 212 F4. Калкулатор. Метод Calculate(double a, double b, char op) връща резултата за +, -, * или /. Операцията се избира с if.
105+10 + 5 = 155. Триъгълник с параметър. Обещахме го в миналия урок. Метод PrintTriangle(int height) извежда правоъгълен триъгълник от звездички с височина height. За 3:
** ** * *По-точно, за любопитните
Внимавай с 5 / 9 във формулата за Целзий. И двете числа са цели, затова делението е целочислено и резултатът е 0. Пиши (f - 32) * 5 / 9: тогава f - 32 е double и цялата сметка е дробна.
Упражнение
Методи за масиви
Всяка задача е един метод, който получава масив (или дума) и връща резултат. Накрая ги събери в една програма.
Sum,SumEvenиSumOdd: сумата на всички, на четните и на нечетните числа в масива.Reverse: връща нов масив с числата в обратен ред.MaxиMin: най-голямото и най-малкото число.IsPalindrome(string word): дали думата се чете еднакво отпред назад и отзад напред.SumDiagonalsиSumDiagonalsOnce: сумата по двата диагонала на квадратна матрица, с централния елемент два пъти и веднъж.- Всичко заедно: за масива
{ 1, 2, 3, 4, 5 }, числото 7 (сIsPrimeот горната карта), думите „капак“ и „АБВГД“ и матрицата 3 × 3 с числата от 1 до 9.
Сума: 15, Четни: 6, Нечетни: 9Обърнат: [5, 4, 3, 2, 1]Макс: 5, Мин: 17 е просто: Trueкапак: True, АБВГД: FalseСума с повторение: 30, Сума без повторение: 25Тест