Към съдържанието
wannacode

Параметри и 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);
Отговор

Проблем

Защо цената не се намали?

Написал си метод за 10% отстъпка и си го извикал:

static void ApplyDiscount(double price)
{
price = price * 0.9;
}
double price = 100;
ApplyDiscount(price);
Console.WriteLine(price); // 100
Изход
100

Цената пак е 100. Методът не дава грешка, а отстъпката я няма. Къде отиде?

Виж го

Методът получава копие

static void ApplyDiscount(double price)
{
price = price * 0.9;
}
double price = 100;
ApplyDiscount(price);
Console.WriteLine(price); // 100
Стъпка по стъпка, с думи
  1. В Main има променлива price = 100.
  2. Викаш ApplyDiscount(price): за метода се заделя нова памет.
  3. Стойността се копира в неговия параметър price.
  4. Методът намалява своето копие: 100 * 0.9 = 90.
  5. Методът свършва и паметта му изчезва, заедно с копието.
  6. А 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
Стъпка по стъпка, с думи
  1. В Main: price = 100.
  2. Викаш ApplyDiscount(price): заделя се памет за метода.
  3. Стойността се копира в параметъра price.
  4. return price * 0.9: резултатът е 90.
  5. Резултатът се връща в Main и се записва в price.
  6. Сега 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);
Изход
15
1 10

Ползвай ги рядко. Метод, който връща резултат с return, се чете по-лесно.

Пробвай

Какъв е резултатът?

Методът смята ДДС от 20% върху цената. Какъв тип трябва да пише на празното място?

static  Vat(double price)
{
    return price * 0.2;
}

Пробвай

Върнато, но изгубено

Какво ще отпечата програмата?

static int Reserve(int seats)
{
seats = seats - 2;
Console.WriteLine("вътре: " + seats);
return seats;
}
int seats = 10;
Reserve(seats);
Console.WriteLine("отвън: " + 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));
Изход
0
4.99

Щом стигне до return, методът свършва веднага. Затова при 62 € вторият return не се изпълнява и не ни трябва else.

Метод с резултат трябва да върне стойност по всеки път. Ако махнеш последния ред, програмата не се компилира: „not all code paths return a value“.

Пробвай

Намери грешката

Членовете на клуба имат 10% отстъпка, останалите плащат пълната цена. Но отстъпка получават всички. На кой ред е грешката?

Избери реда с грешката.

Упражнение

Методи, които смятат

Реши задачите в редактора си. Всеки метод получава каквото му трябва като параметри и връща резултата. Печата се в Main.

1. Средно аритметично. Метод Average(int[] values) връща средното на числата в масива. В Main прочети от клавиатурата колко са числата, после самите числа.

Вход
5
10
15
20
25
30
Изход
Средно аритметично: 20

2. Просто число. Метод IsPrime(int n) връща дали числото е просто (дели се само на 1 и на себе си). За 7 връща True, за 12 False.

3. Температури. Методи ToFahrenheit(double c) и ToCelsius(double f). F = C · 9 / 5 + 32. Прочети температура и мерна единица (C или F) и отпечатай превърнатата.

Вход
100
C
Изход
100 C = 212 F

4. Калкулатор. Метод Calculate(double a, double b, char op) връща резултата за +, -, * или /. Операцията се избира с if.

Вход
10
5
+
Изход
10 + 5 = 15

5. Триъгълник с параметър. Обещахме го в миналия урок. Метод PrintTriangle(int height) извежда правоъгълен триъгълник от звездички с височина height. За 3:

Изход
*
* *
* * *
По-точно, за любопитните

Внимавай с 5 / 9 във формулата за Целзий. И двете числа са цели, затова делението е целочислено и резултатът е 0. Пиши (f - 32) * 5 / 9: тогава f - 32 е double и цялата сметка е дробна.

Упражнение

Методи за масиви

Всяка задача е един метод, който получава масив (или дума) и връща резултат. Накрая ги събери в една програма.

  1. Sum, SumEven и SumOdd: сумата на всички, на четните и на нечетните числа в масива.
  2. Reverse: връща нов масив с числата в обратен ред.
  3. Max и Min: най-голямото и най-малкото число.
  4. IsPalindrome(string word): дали думата се чете еднакво отпред назад и отзад напред.
  5. SumDiagonals и SumDiagonalsOnce: сумата по двата диагонала на квадратна матрица, с централния елемент два пъти и веднъж.
  6. Всичко заедно: за масива { 1, 2, 3, 4, 5 }, числото 7 (с IsPrime от горната карта), думите „капак“ и „АБВГД“ и матрицата 3 × 3 с числата от 1 до 9.
Изход от задача 6
Сума: 15, Четни: 6, Нечетни: 9
Обърнат: [5, 4, 3, 2, 1]
Макс: 5, Мин: 1
7 е просто: True
капак: True, АБВГД: False
Сума с повторение: 30, Сума без повторение: 25

Тест

Провери се

1. В static double Vat(double price) кое е параметърът?
2. Методът променя своя параметър. Какво става с променливата, подадена при извикването?
3. Какво прави return?
4. Метод е обявен с тип double. Какво трябва да е вярно?
5. Какво прави редът price = ApplyDiscount(price);?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·