Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Другие элементы меню 2 страница




Статические поля и методы арифметических классов

Все арифметические классы, в том числе класс int, обладают двумя полезными полями (свойствами) – MinValue и MaxValue. Эти поля возвращают минимальное и максимальное значение, которое могут иметь экземпляры класса. Поля являются статическими и потому недоступны для экземпляров класса и могут быть вызваны только при указании имени класса. Разумно привести пример вызова этих полей для класса int и, например, для класса double:

// Min и Max значения типов

Console.WriteLine("Class int");

Console.WriteLine("Мин. значение int = " + int. MinValue);

Console.WriteLine("Макс. значение int = " + int. MaxValue);

Console.WriteLine("Class double");

Console.WriteLine("Мин. значение double = " + double. MinValue);


Console.WriteLine("Макс. значение double = " + double. MaxValue);

Все арифметические классы, в том числе класс int, обладают перегруженным статическим методом Parse, у которого первым обязательным параметром является строка, задающая значение соответствующего арифметического типа в привычной для данного региона (локализованной) форме. Форматом строки и стилем ее представления можно управлять с помощью других параметров метода Parse. Вот пример вызова этого метода для классов int и double:

/// <summary>

/// Преобразования типа с использованием метода Parse

/// </summary>

public void Parsing()

{

//method Parse

Console.WriteLine("Введите целое");

string strdata = Console.ReadLine();

int intdata = int. Parse(strdata);

Console.WriteLine("Введите число с дробной частью и порядком");

strdata = Console.ReadLine();

double doubdata = double. Parse(strdata);

Console.WriteLine("intdata = {0}; doubdata = {1}",

intdata, doubdata);

}

//Parsing

Как видите, метод Parse с успехом заменяет соответствующий метод класса Convert.

На рис. 6.3 можно увидеть консольный вывод, полученный в результате работы процедуры Parsing:

Рис. 6.3. Результаты работы процедуры Parsing

Операция new

Пора вернуться к основной теме – операциям, допустимым в языке C#. Последней из еще нерассмотренных операций высшего уровня приоритета является операция new. Ключевое слово new используется в двух контекстах, – как модификатор и как операция в инициализирующих выражениях объявителя. Во втором случае результатом выполнения операции new является создание нового объекта и вызов соответствующего конструктора. Примеров подобного использования операции new было приведено достаточно много, в том числе и в этой лекции.

Арифметические операции

В языке C# имеются обычные для всех языков арифметические операции – «+, -, *, /, %». Все они перегружены. Операции «+» и «-» могут быть унарными и бинарными. Операция деления «/» над целыми типами осуществляет деление нацело, для типов с плавающей и фиксированной точкой обычное деление. Операция «%» определена над всеми арифметическими типами и возвращает остаток от деления нацело. Тип результата зависит от типов операндов. Приведу пример вычислений с различными арифметическими типами:

/// <summary>

/// Арифметические операции

/// </summary>

public void Ariphmetica()

{

int n = 7,m =3, p,q;

p= n/m; q= p*m + n%m;

if (q==n) Console.WriteLine("q=n");

else Console.WriteLine("q!=n");

double x=7, y =3, u,v,w;

u = x/y; v= u*y;

w= x%y;

if (v==x) Console.WriteLine("v=x");

else Console.WriteLine("v!=x");

decimal d1=7, d2 =3, d3,d4,d5;

d3 = d1/d2; d4= d3*d2;

d5= d1%d2;

if (d4==d1) Console.WriteLine("d4=d1");

else Console.WriteLine("d4!=d1");

}// Ariphmetica

При проведении вычислений в двух первых случаях проверяемое условие оказалось истинным, в третьем – ложным. Для целых типов можно исходить из того, что равенство n = n/m*m+n%m истинно. Для типов с плавающей точкой выполнение точного равенства x = x/y*y следует считать скорее случайным, а не закономерным событием. Законно невыполнение этого равенства, как это имеет место при вычислениях с фиксированной точкой.

Операции отношения

Операции отношения стоит просто перечислить, в объяснениях они не нуждаются. Всего операций 6 – (==,!=, <, >, <=, >=). Для тех, кто не привык работать с языком C++, стоит обратить внимание на запись операций «равно» и «не равно».

Операции проверки типов

Операции проверки типов is и as будут рассмотрены в последующих лекциях. (Смотри, например, лекцию 19).

Операции сдвига

Операции сдвига вправо “ >> ” и сдвига влево “ << ” в обычных вычислениях применяются редко. Они особенно полезны, если данные рассматриваются, как строка битов. Результатом операции является сдвиг строки битов влево или вправо на K разрядов. В применении к обычным целым положительным числам сдвиг вправо равносилен делению нацело на 2K, а сдвиг влево – умножению на 2K. Для отрицательных чисел сдвиг влево и деление дают разные результаты, отличающиеся на 1. В языке C# операции сдвига определены только для некоторых целочисленных типов – int, uint, long, ulong. Величина сдвига должна иметь тип int. Вот пример применения этих операций:

/// <summary>

/// операции сдвига

/// </summary>

public void Shift()

{

int n = 17,m =3, p,q;

p= n>>2; q = m<<2;

Console.WriteLine("n= " + n + "; m= " +

m + "; p=n>>2 = "+p + "; q=m<<2 " + q);

long x=-75, y =-333, u,v,w;

u = x>>2; v = y<<2; w = x/4;

Console.WriteLine("x= " + x + "; y= " +

y + "; u=x>>2 = "+u + "; v=y<<2 " + v +

"; w = x/4 = " + w);

}// Shift

Логические операции

Начну с предупреждения тем, кто привык к языку C++. Правила работы с логическими выражениями в языках C# и C++ имеют принципиальные различия. В языке C++ практически для всех типов существует неявное преобразование в логический тип. Правило преобразования простое, – ненулевые значения трактуются как истина, нулевое – как ложь. В языке C# неявных преобразований к логическому типу нет даже для целых арифметических типов. Поэтому вполне корректная в языке C++ запись:

int k1 = 7;

if (k1) Console.WriteLine("ok!");

незаконна в программах на C#. На этапе трансляции возникнет ошибка, поскольку вычисляемое условие имеет тип int, а неявное преобразование этого типа к типу bool отсутствует.

В языке C# более строгие правила действуют и для логических операций. Так запись

if (k1 && (x>y))

корректная в языке C++, приводит к ошибке в программах на C#, поскольку операция && определена только для операндов типа bool, а в данном выражении один из операндов имеет тип int. В языке C# в данных ситуациях следует использовать записи:

if (k1>0)

if ((k1>0) && (x>y))

После этого важного предупреждения перейду к более систематическому изложению некоторых особенностей выполнения логических операций. Также как и в языке C++ логические операции делятся на две категории, - одни выполняются над логическими значениями операндов, другие осуществляют выполнение логической операции над битами операндов. По этой причине в C# существуют две унарные операции отрицания – логическое отрицание, заданное операцией «!», и побитовое отрицание, заданное операцией «~». Первая из этих операций определена над операндом типа bool, вторая над операндом целочисленного типа, начиная с типа int и выше (int, uint, long, ulong). Результатом операции во втором случае является операнд, в котором каждый бит заменен его дополнением. Приведу пример:

/// <summary>

/// Логические выражения

/// </summary>

public void Logic()

{

//операции отрицания ~,!

bool b1,b2;

b1 = 2*2==4;

b2 =!b1;

//b2= ~b1;

uint j1 =7, j2;

j2= ~j1;

//j2 =!j1;

int j4 = 7, j5;

j5 = ~j4;

Console.WriteLine("uint j2 = " + j2 +

" int j5 = " + j5);

}// Logic

В этом фрагменте закомментированы операторы, приводящие к ошибкам. В первом случае была сделана попытка применения операции побитового отрицания к выражению типа bool, во втором – логическое отрицание применялось к целочисленным данным. И то, и другое в C# незаконно. Обратите внимание на разную интерпретацию побитового отрицания для беззнаковых и знаковых целочисленных типов. Для переменных j5 и j2 строка битов, задающая значение, одна и та же, но интерпретируется по-разному. Соответствующий вывод таков:

uint j2 = 4294967288 int j5 = -8

Бинарные логические операции «&& - условное И» и «|| - условное ИЛИ» определены только над данными типа bool. Операции называются условными или краткими, поскольку будет ли вычисляться второй операнд, зависит от уже вычисленного значения первого операнда. В операции «&&», если первый операнд равен значению false, то второй операнд не вычисляется и результат операции равен false. Аналогично, в операции «||», если первый операнд равен значению true, то второй операнд не вычисляется и результат операции равен true. Ценность условных логических операций не в их эффективности по времени выполнения. Часто они позволяют вычислить логическое выражение, имеющее смысл, но в котором второй операнд не определен. Приведу в качестве примера классическую задачу поиска по образцу в массиве, когда в массиве разыскивается элемент с заданным значением (образец). Такой элемент может быть, а может и не быть в массиве. Вот типичное решение этой задачи в упрощенном виде, но передающем суть дела:

//Условное And - &&

int [] ar= {1,2,3};

int search = 7;

int i=0;

while ((i < ar.Length) && (ar[i]!= search)) i++;

if (i<ar.Length) Console.WriteLine("Образец найден");

else Console.WriteLine("Образец не найден");

Если значение переменной search (образца) не совпадает ни с одним из значений элементов массива ar, то последняя проверка условия цикла while будет выполняться при значении i, равном ar.Length. В этом случае первый операнд получит значение false, и, хотя второй операнд в этом случае не определен, цикл нормально завершит свою работу. Второй операнд не определен в последней проверке, поскольку индекс элемента массива выходит за допустимые пределы (в C# индексация элементов начинается с нуля). Заметьте, «нормальная» конъюнкция требует вычисления обеих операндов, поэтому ее применение в этой программе приводило бы к выбросу исключения в случае, когда образца нет в массиве.

Три бинарные побитовые операции – ” & - AND “, “ | - OR ”, “ ^ - XOR” используются двояко. Они определены как над целыми типами выше int, так и над булевыми типами. В первом случае они используются как побитовые операции, во втором – как обычные логические операции. Иногда необходимо, чтобы оба операнда вычислялись в любом случае, тогда без этих операций не обойтись. Вот пример первого их использования:

//Логические побитовые операции And, Or, XOR (&,|,^)

int k2 = 7, k3 = 5, k4, k5, k6;

k4 = k2 & k3; k5 = k2| k3; k6 = k2^k3;

Console.WriteLine("k4 = " + k4 + " k5 = " +

k5 + " k6 = " + k6);

Приведу результаты вывода:

k4 = 5 k5 = 7 k6 =2

Приведу пример поиска по образцу с использованием логического AND:

i=0; search = ar[ar.Length - 1];

while ((i < ar.Length) & (ar[i]!= search)) i++;

if (i<ar.Length) Console.WriteLine("Образец найден");

else Console.WriteLine("Образец не найден");

В данном фрагменте гарантируется наличие образца поиска в массиве и фрагмент будет успешно выполнен. В тех же случаях, когда массив не содержит элемента search, будет выброшено исключение. В этом есть содержательный смысл – появление исключения может быть признаком ошибки в данных, что требует специальной обработки ситуации.

Условное выражение

В C#, как и в C++, разрешены условные выражения. Конечно, без них можно обойтись, заменив их условным оператором. Вот простой пример их использования, поясняющий синтаксис их записи:

//Условное выражение

int a = 7, b= 9, max;

max= (a>b)? a:b;

Console.WriteLine("a = " + a + "; b= " + b +

"; max(a,b) = " + max);

Условное выражение начинается с условия, заключенного в круглые скобки, после которого следует знак вопроса и пара выражений, разделенных двоеточием «:». Условием является выражение типа bool. Если оно истинно, то из пары выражений выбирается первое, в противном случае результатом является значение второго выражения. В данном примере переменная max получит значение 9.

Операция приведения к типу

Осталось рассмотреть еще одну операцию – приведение к типу. Эта операция приоритета 1 имеет следующий синтаксис:

(type) <унарное выражение>

Она задает явное преобразование типа, определенного выражением, к типу, указанному в скобках. Чтобы операция была успешной, необходимо, чтобы такое явное преобразование существовало. Напомню, существуют явные преобразования внутри арифметического типа, но не существует, например, явного преобразования арифметического типа в тип bool. При определении пользовательских типов для них могут быть определены явные преобразования в другие, в том числе, встроенные типы. О явных преобразованиях говорилось достаточно много, приводились и примеры. Поэтому ограничусь совсем простым примером:

//cast

int p;

p = (int)x;

//b = (bool)x;

В данном примере явное преобразование из типа double в тип int выполняется, а преобразование double к типу bool приводит к ошибке, потому и закомментировано.

Вариант 1

13. Верно, что приоритет операций выше:

q умножения чем сложения;

q отношения чем умножения;

q эквивалентности чем конъюнкции;

q унарных чем бинарных.

14. В результате объявления:
int x=1, y=2, z= ((x|y + ++x)>5)? x|y: ++x +2;
переменные x, y, z получат значения:

q x=1; y=2; z=4;

q x=2; y=2; z=4;

q x=3; y=2; z=5;

q возникнет ошибка на этапе трансляции;

q возникнет ошибка на этапе выполнения;

q x=1; y=2; z=3;

15. Отметьте истинные высказывания:

q операция typeof может выполняться только в небезопасных блоках;

q метод Parse определен для всех арифметических типов;

q метод Parse позволяет проводить преобразования внутри арифметического типа;

q метод GetType позволяет получить тот же результат, что и операция typeof.

Вариант 2

16. Верно, что приоритет операций выше:

q условных И, ИЛИ чем логических И, ИЛИ;

q отношения чем логических;

q арифметических чем отношения;

q И чем ИЛИ.

17. В результате объявления:
int x=2, y=5, z= ((x|y +x++)>=9)? x|y: ++x +2;
переменные x, y, z получат значения:

q x=3; y=5; z=7;

q x=2; y=5; z=5;

q x=2; y=5; z=7;

q возникнет ошибка на этапе трансляции;

q возникнет ошибка на этапе выполнения;

q x =3; y=5; z=8;

18. Отметьте истинные высказывания:

q операция sizeof может выполняться только в небезопасных блоках;

q операция логического (побитового) отрицания определена над данными арифметического типа и типа bool;

q метод Parse позволяет проводить преобразования арифметического типа в строковый;

q порядок выполнения всех операций в C# левосторонний.

Вариант 3

16. Верно, что приоритет операций выше:

q вычитания чем сложения;

q исключительного Или чем ИЛИ;

q префиксных чем постфиксных;

q эквивалентности чем присваивания.

17. В результате объявления:
int x=2, y=3, z= ((x|--y +y)>5)? x|y: ++x +2;
переменные x, y, z получат значения:

q x=1; y=2; z=4;

q x=2; y=2; z=4;

q x=2; y=2; z=2;

q возникнет ошибка на этапе трансляции;

q возникнет ошибка на этапе выполнения;

q x=2; y=3; z=3;

18. Отметьте истинные высказывания:

q операция new может выполняться только при объявлении переменной;

q метод Parse определен для всех типов;

q вызов MaxValue возвращает размер памяти, отводимой значениям типа;

q условие в операторе if записано c ошибкой: if(2*2 = 4).

 

Лекция 7. Присваивание и встроенные функции

Присваивание. Новинка C# - определенное присваивание. Классы Math, Random и встроенные функции.

Ключевые слова: присваивание; определенное присваивание; встроенные классы; встроенные функции; класс Math; класс Random.

Присваивание

В большинстве языков программирования присваивание это оператор, а не операция. В языке C# присваивание унаследовало многие особенности присваивания языка C++. В C# присваивание толкуется, как операция, используемая в выражениях. Однако в большинстве случаев присваивание следует рассматривать и использовать как обычный оператор.

Рассмотрим полезный случай реального использования присваивания как операции. В ситуации, называемой множественным присваиванием, списку переменных присваивается одно и тоже значение. Вот пример:

/// <summary>

/// анализ присваивания

/// </summary>

public void Assign()

{

double x,y,z,w =1, u =7, v= 5;

x = y = z = w =(u+v+w)/(u-v-w);

}// Assign

По мере изложения в метод Assign будут добавляться фрагменты кода, связанные с рассматриваемой темой присваивания.

О семантике присваивания говорилось уже достаточно много. Но следует внести еще некоторые уточнения. Правильно построенное выражение присваивания состоит из левой и правой части. Левая часть – это список переменных, в котором знак равенства выступает в качестве разделителя. Правая часть – это выражение. Выражение правой части вычисляется, при необходимости приводится к типу переменных левой части, после чего все переменные левой части получают значение вычисленного выражения. Последние действия можно рассматривать, как побочный эффект операции присваивания. Заметьте, все переменные в списке левой части должны иметь один тип или неявно приводиться к одному типу. Операция присваивания выполняется справа налево, поэтому вначале значение выражения получит самая правая переменная списка левой части, при этом значение самого выражения не меняется. Затем значение получает следующая справа переменная списка и так до тех пор, пока не будет достигнут конец списка. Так что реально можно говорить об одновременном присваивании, в котором все переменные списка получают одно и тоже значение. В нашем примере несмотря на то, что переменная w первой получит значение, а выражение в правой части зависит от w, все переменные будут иметь значение 13.0. Рассмотрим еще один фрагмент кода:

bool b;

x=5; y=6;

//b= x=y;

//if (x=y) z=1;else z=-1;

В программе на языке C++ можно снять комментарии с операторов и этот фрагмент кода компилировался и выполнялся бы без ошибок. Другое дело, что результат мог быть некорректен, поскольку, вероятнее всего, операция присваивания “ x=y ” написана по ошибке и ее следует заменить операцией эквивалентности «x==y». В языке C# оба закомментированных оператора, к счастью, приведут к ошибке трансляции, поскольку результат присваивания имеет тип double, для которого нет неявного преобразования в тип bool. На C# такая программа будет выполняться, только если x и y будут иметь тип bool, но в этом случае, возможно, применение операции присваивания имеет смысл. С типами double корректная программа на C# может быть такой:

x =y;

b= (y!=0);

if (y!=0) z=1; else z = -1;

В программе появился лишний оператор, но исчезла двусмысленность, порождаемая операцией присваивания.

Специальные случаи присваивания

В языке C++ для двух частных случая присваивания предложен отдельный синтаксис. Язык C# наследовал эти полезные свойства. Для присваиваний вида “ x=x+1 ”, в которых переменная увеличивается или уменьшается на 1, используются специальные префиксные и постфиксные операции “++” и «--». Другой важный частный случай – это присваивания вида:

X = X <operator> (expression)

Для таких присваиваний используется краткая форма записи:

X <operator>= expresion

В качестве операции разрешается использовать арифметические, логические (побитовые) операции и операции сдвига языка C#. Семантика такого присваивания достаточно очевидна и я ограничусь простым примером:

x += u+v; y /=(u-v);

b &= (x<y);

Однако и здесь есть один подводный камень, когда x= x+a не эквивалентно x +=a. Рассмотрим следующий пример:

byte b3 = 21;

b3 +=1; //Это допустимо

//b3 = b3+1; //А это недопустимо:результат типа int

Закомментированный оператор приведет к ошибке компиляции, поскольку правая часть имеет тип int, а неявное преобразование к типу byte отсутствует. Следует понимать, что преимущество первой формы записи только кажущееся, если при инициализации переменная b получит допустимое значение 255, то следующий оператор присваивания в краткой форме не выдаст ошибки, но даст неверный результат, а это самое худшее, что может случиться в программе. Так что надежнее пользоваться полной формой записи присваивания не экономя на паре символов в записи.

Определенное присваивание

Присваивание в языке C# называется определенным присваиванием (definite assignment). Это определение отражает тот уже обсуждавшийся факт, что все используемые в выражениях переменные должны быть ранее инициализированы, и иметь определенные значения. Единственное, за чем компилятор не следит, так это за инициализацией переменных массива. Для них используется инициализация элементов, задаваемая по умолчанию. Приведу пример:

//определенное присваивание

int an =0; //переменные должны быть инициализированы

for (int i= 0;i<5;i++)

{an =i+1;}

x+=an; z+=an; y = an;

string [] ars = new string [3];

double [] ard = new double [3];

for (int i= 0;i<3;i++)

{

//массивы могут быть без инициализации

ard[i] += i+1;

ars[i] += i.ToString()+1;

Console.WriteLine("ard[" +i + "]=" +ard[i] +

"; ars[" +i + "]=" +ars[i]);

}

Заметьте, в этом фрагменте переменная an обязана быть инициализирована, а массивы ard и ars не инициализируются и спокойно участвуют в вычислениях.

Еще раз о семантике присваивания

Подводя итоги рассмотрения присваивания x=e, следует отметить, что семантика присваивания далеко не столь проста, как может показаться с первого взгляда. Напомню, что деление типов на значимые и ссылочные приводит к двум семантикам присваивания. Будет ли семантика присваивания значимой или ссылочной определяется типом левой части присваивания. Переменные значимых типов являются единоличными владельцами памяти, в которой хранятся их значения. При значимом присваивании память для хранения значений остается та же, меняются сами значения, хранимые в памяти. Переменные ссылочных типов (объекты) являются ссылками на реальные объекты динамической памяти. Ссылки могут разделять одну и ту же область памяти – ссылаться на один и тот же объект. Ссылочное присваивание – это операция над ссылками. В результате ссылочного присваивания ссылка начинает указывать на другой объект.

Рассмотрим объявления:

int x=3, y=5;

object obj1, obj2;

Здесь объявлены четыре сущности – две переменные значимого типа и две объектного. Значимые переменные x и y проинициализированы и имеют значения, объектные переменные obj1 и obj2 являются пустыми ссылками со значением void. Рассмотрим присваивания:

obj1 = x; obj2 = y;

Эти присваивания ссылочные (из-за типа левой части), поэтому правая часть приводится к ссылочному типу. В результате неявного преобразования – операции boxing – в динамической памяти создаются два объекта, обертывающие соответственно значения переменных x и y. Сущности obj1 и obj2 получают значения ссылок на эти объекты.

Класс Math и его функции

Кроме переменных и констант первичным материалом построения выражений являются функции. Большинство функций в проекте будут созданы самим программистом, но не обойтись и без встроенных функций. Умение работать в среде Visual Studio.Net предполагает знание встроенных возможностей этой среды, знание возможностей каркаса Framework.Net, пространств имен, доступных при программировании на языке C#, соответствующих встроенных классов и функций этих классов. Продолжим знакомство с возможностями, предоставляемыми пространством имен System. Мы уже познакомились с классом Convert этого пространства и частично с классом Console. Давайте рассмотрим еще один класс – класс Math, содержащий стандартные математические функции, без которых трудно обойтись при построении многих выражений. Этот класс содержит два статических поля, задающих константы E и PI, и 23 статических метода. Методы задают:

тригонометрические функции – Sin, Cos, Tan;

обратные тригонометрические функции – ASin, ACos, ATan, ATan2(sinx, cosx);

гиперболические функции – Tanh, Sinh, Cosh;

экспоненту и логарифмические функции – Exp, Log, Log10;

модуль, корень, знак – Abs, Sqrt, Sign;

функции округления – Ceiling, Floor, Round;

Минимум, Максимум, Степень, Остаток – Min, Max, Pow, IEEEReminder.

В особых пояснениях эти функции не нуждаются. Приведу пример:

/// <summary>

/// работа с функциями класса Math

/// </summary>

public void MathFunctions()

{

double a, b,t,t0,dt,y;

string NameFunction;

Console.WriteLine("Введите имя F(t)исследуемой функции a*F(b*t)" +

" (sin, cos, tan, cotan)");

NameFunction = Console.ReadLine();

Console.WriteLine("Введите параметр a (double)");




Поделиться с друзьями:


Дата добавления: 2014-12-25; Просмотров: 615; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.163 сек.