double a,b,c; – описание переменных a,b,c. По смыслу задачи это длины сторон треугольника.
Console.WriteLine("Vvedite a,b,c так, чтобы получился треугольник");
a = Convert.ToDouble(Console.ReadLine());
b = Convert.ToDouble(Console.ReadLine());
c = Convert.ToDouble(Console.ReadLine()); - ввод значений a,b,c с клавиатуры. Причем ответсвенность за ввод правильных (корректных) значений сторон треугольника переложена на пользователя. Если будут введены «плохие» данные, ну что ж, Вас предупреждали!
double ug_a = ugol(a, b, c); // угол a – инициализация переменной ug_a типа double и присваивание ей значения, получающегося после вызова метода ugol. При вызове ugol значение фактического параметра a будет скопировано в формальный параметр a, значение фактического параметра b будет скопировано в формальный параметр b, значение фактического параметра c будет скопировано в формальный параметр c .
Далее Main() остановится, и начнет выполняться метод ugol. Говорят, что управление передано в метод. По значениям формальных параметров будет вычислено значение локальной переменой aa, и оно будет возвращено в имя ugol. При этом метод ugol прекратит выполнение и передаст управление в метод Main.
Следует отметить, что переменные a, b, c, описанные как формальные параметры, и a,b,c, использующиеся как фактические параметры – разные переменные, хотя и записаны одинаковыми идентификаторами. Почему они разные? Память под них отводится в разных местах. Под формальные параметры – это память, которая отведена в методе ugol. Под переменые a,b,c память выделяется в методе Main(). Значит они разные.
Далее.
double ug_b = ugol(b, a, c); // угол b – первый параметр – переменная b. Значит (внимание!) в формальный параметр a будет передано значение переменной b. Значение переменной a попадет в формальный параметрb, а значение c попадет в формальный параметр c.
И наконец.
double ug_c = ugol(c, b, a); // угол c - первый параметр – переменная c. Значит в формальный параметр a будет передано значение переменной c .
Ну а дальше значения ug_a, ug_b, ug_c выводятся на экран.
Таким образом с использованием одного метода вычислили три угла, правда они измерены в радианах.
Напишем еще один метод, который будет переводить углы из радианов в градусы. Его код приведен в примере 2.2.
Пример 2.2
static double Rad_v_Grad(double x)
{
return 180 * x / Math.PI;
}
Представляется, что этот код в пояснениях не нуждается.
Теперь тело класса Program будет выглядеть, как в примере 2.3.
Пример 2.3 Класс Program примера 2.1.
class Program
{
static double ugol(double a, double b, double c)
{
double aa;
aa=(b*b+c*c-a*a)/(2*b*c);
aa = Math.Acos(aa);
return aa;
}
// Это новое
static double Rad_v_Grad(double x)
{
return 180 * x / Math.PI;
}
static void Main(string[] args)
{
double a,b,c;
Console.WriteLine("Vvedite a,b,c");
a = Convert.ToDouble(Console.ReadLine());
b = Convert.ToDouble(Console.ReadLine());
c = Convert.ToDouble(Console.ReadLine());
double ug_a = ugol(a, b, c);
double ug_b = ugol(b, a, c);
double ug_c = ugol(c, b, a);
// это добавили
ug_a = Rad_v_Grad(ug_a);
ug_b = Rad_v_Grad(ug_b);
ug_c = Rad_v_Grad(ug_c);
Console.WriteLine("a1=" + ug_a + " a2=" + ug_b + " a3=" + ug_c);
Console.ReadLine();
}
}
Рис. 2.2. Результаты работы программы примера 2.3
И последнее. Собственно решение задачи – это последовательность, состоящая из шести вызовов методов в Main()-е. Это много, можно шесть раз ошибиться. Сделаем надежнее. Организуем метод, вызов которого в Main решит всю задачу. На вход этого метода подадим три стороны, на выходе – три угла в градусах. Этим самым возьмем решение всей задачи в свои руки, если так будем делать и дальше, то скорее всего это приведет к созданию более надежных программ. Ведь теперь ошибиться можно, только перепутав последовательность фактических параметров.
Но есть особенность. Если метод возвращает значение типа double или int или какое-либо другое, то через имя метода можно возвратить всего лишь одно значение. А тут этих значений три. Здесь-то и понадобится механизм передачи параметров по адресу. Ведь значения вычисленных углов – это типичные выходные параметры. Далее. В качестве возвращаемого типа метода может быть записано значение void, что значит буквально «ничего не возвращать». Что при этом изменится по сравнению с методом, у которого возвращаемый тип отличается от void (double, int, string и т.п.)? В теле метода, который ничего не возвращает, не должно быть оператора return, кроме этого изменится вызов метода – он будет вызываться просто по имени.
Чтобы передача параметров была организована по адресу, один из вариантов – использовать служебное слово out. Причем его ( out ) надо писать как перед формальным параметром, сообщая компилятору, что будет передача по адресу, так и перед соответствующими фактическими параметрами. Такая организация передачи адреса говорит о том, что параметры будут строго выходными. Что это значит? Это значит, что в теле метода этому формальному параметру обязательно должно быть присвоено какое-либо значение. А вот соответствующему фактическому параметру до вызова метода никакого значения присваивать не следует.
Другой вариант передачи по адресу – использовать служебной слово ref. В этом случае формальный параметр может быть как входным, так и выходным. При этом в теле метода совершенно необязательно ему присваивать какое-либо значение. А вот соответствующему фактическому параметру присвоить значение обязательно придется еще до вызова метода.
Пример 2.4. Окончательный вариант исходного кода программы примера 2.1
class Program
{
static double ugol(double a, double b, double c)
{
double aa;
aa=(b*b+c*c-a*a)/(2*b*c);
aa = Math.Acos(aa);
return aa;
}
static double Rad_v_Grad(double x)
{
return 180 * x / Math.PI;
}
// это новое
static void TriUgla(double a,double b,double c,out double ug_a,out double ug_b,out double ug_c)
{
ug_a = ugol(a, b, c);
ug_b = ugol(b, a, c);
ug_c = ugol(c, b, a);
ug_a = Rad_v_Grad(ug_a);
ug_b = Rad_v_Grad(ug_b);
ug_c = Rad_v_Grad(ug_c);
}
static void Main(string[] args)
{
double a,b,c;
Console.WriteLine("Vvedite a,b,c");
a = Convert.ToDouble(Console.ReadLine());
b = Convert.ToDouble(Console.ReadLine());
c = Convert.ToDouble(Console.ReadLine());
double ug_a,ug_b,ug_c;
// здесь изменили
TriUgla(a, b, c, out ug_a, out ug_b, out ug_c);// решается вся задача
Console.WriteLine("a1=" + ug_a + " a2=" + ug_b + " a3=" + ug_c);
Console.ReadLine();
}
}
Рис. 2.3. Результаты работы программы примера 2.6
Дата: 2019-11-01, просмотров: 210.