В большинстве языков программирования
Возьмем полезный случай реального использования
/// <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++ для двух частных случаев x=x+1 ", в которых переменная увеличивается или уменьшается на единицу, используются специальные префиксные и постфиксные операции " ++ " и " -- ". Другой важный частный случай - это
X = X <operator> (expression)
Для таких
X <operator>= expression
В качестве операции разрешается использовать арифметические, логические (побитовые) операции и операции сдвига языка 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, то следующий оператор
//определенное присваивание
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 получают значения ссылок на эти объекты.
Кроме переменных и констант, первичным материалом для построения выражений являются функции. Большинство их в проекте будут созданы самим программистом, но не обойтись и без System. Мы уже познакомились с классом Convert этого пространства и частично с классом Console. Давайте рассмотрим еще один класс - 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, IEEERemainder.В особых пояснениях эти функции не нуждаются. Приведу пример:
/// <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)");
a= double.Parse(Console.ReadLine());
Console.WriteLine("Введите параметр b (double)");
b= double.Parse(Console.ReadLine());
Console.WriteLine("Введите начальное время t0(double)");
t0= double.Parse(Console.ReadLine());
const int points = 10;
dt = 0.2;
for(int i = 1; i<=points; i++)
{
t = t0 + (i-1)* dt;
switch (NameFunction)
{
case ("sin"):
y = a*Math.Sin(b*t);
break;
case ("cos"):
y = a*Math.Cos(b*t);
break;
case ("tan"):
y = a*Math.Tan(b*t);
break;
case ("cotan"):
y = a/Math.Tan(b*t);
break;
case ("ln"):
y = a*Math.Log(b*t);
break;
case ("tanh"):
y = a*Math.Tanh(b*t);
break;
default:
y=1;
break;
}//switch
Console.WriteLine ("t = " + t + "; " + a +"*" +
NameFunction +"(" + b + "*t)= " + y + ";");
}//for
double u = 2.5, v = 1.5, p,w;
p= Math.Pow(u,v);
w = Math.IEEERemainder(u,v);
Console.WriteLine ("u = " + u + "; v= " + v +
"; power(u,v)= " + p + "; reminder(u,v)= " + w);
}//MathFunctions
Заметьте, в примерах программного кода я постепенно расширяю диапазон используемых средств. Часть из этих средств уже описана, а часть (например, оператор цикла for и оператор выбора switch ) будут описаны позже. Те, у кого чтение примеров вызывает затруднение, смогут вернуться к ним при повторном чтении книги.
Коротко прокомментирую этот код. В данном примере пользователь определяет, какую функцию он хочет вычислить и при каких значениях ее параметров. Некоторые параметры задаются константами и инициализированными переменными, но для большинства их значения вводятся пользователем. Одна из целей этого фрагмента состоит в демонстрации консольного ввода данных разного типа, при котором используется описанный ранее метод Parse.
Функция, заданная пользователем, вычисляется в операторе switch. Здесь реализован выбор из 6 стандартных функций, входящих в джентльменский набор
Вызов еще двух функций из
(рис 7.1) Результаты работы процедуры MathFunctionsУмение генерировать случайные числа требуется во многих приложениях.
Как и всякий "настоящий" класс, Object, а, следовательно, имеет в своем составе и методы родителя. Рассмотрим только оригинальные методы public, необходимые для генерирования последовательностей случайных чисел. Класс имеет защищенные методы, знание которых полезно при необходимости создания собственных потомков
Начнем рассмотрение с конструктора класса. Он перегружен и имеет две реализации. Одна из них позволяет генерировать неповторяющиеся при каждом запуске серии случайных чисел. Начальный элемент такой серии строится на основе текущей даты и времени, что гарантирует уникальность серии. Этот конструктор вызывается без параметров. Он описан как public Random(). Другой конструктор с параметром - public Random (int) обеспечивает важную возможность генерирования повторяющейся серии случайных чисел. Параметр конструктора используется для построения начального элемента серии, поэтому при задании одного и того же значения параметра серия будет повторяться.
Перегруженный метод public int Next() при каждом вызове возвращает положительное целое, равномерно распределенное в некотором диапазоне. Диапазон задается параметрами метода. Три реализации метода отличаются набором параметров:
public int Next () - метод без параметров выдает целые положительные числа во всем положительном диапазоне типа int ;public int Next (int max) - выдает целые положительные числа в диапазоне [0,max] ;public int Next (int min, int max) - выдает целые числа в диапазоне [min,max].Метод public double NextDouble () имеет одну реализацию. При каждом вызове этого метода выдается новое случайное число, равномерно распределенное в интервале [0,1).
Еще один полезный метод public void NextBytes (byte[] buffer). Так как параметр buffer представляет массив байтов, то, естественно, генерированные случайные числа находятся в диапазоне [0, 255].
Приведу теперь пример работы со случайными числами. Как обычно, для проведения экспериментов по генерации случайных чисел я создал метод Rand в классе Testing. Вот программный код этого метода:
/// <summary>
/// Эксперименты с классом Random
/// </summary>
public void Rand()
{
const int initRnd = 77;
Random realRnd = new Random();
Random repeatRnd = new Random(initRnd);
// случайные числа в диапазоне [0,1)
Console.WriteLine("случайные числа в диапазоне[0,1)");
for(int i =1; i <= 5; i++)
{
Console.WriteLine("Число " + i + "= "
+ realRnd.NextDouble() );
}
// случайные числа в диапазоне[min,max]
int min = -100, max=-10;
Console.WriteLine("случайные числа в диапазоне [" +
min +"," + max + "]");
for(int i =1; i <= 5; i++)
{
Console.WriteLine("Число " + i + "= "
+ realRnd.Next(min,max) );
}
// случайный массив байтов
byte[] bar = new byte[10];
repeatRnd.NextBytes(bar);
Console.WriteLine("Массив случайных чисел в диапазоне
[0, 255]");
for(int i =0; i < 10; i++)
{
Console.WriteLine("Число " + i + "= " +bar[i]);
}
}//Rand
Приведу краткий комментарий к тексту программы. Вначале создаются два объекта realRnd позволяет генерировать неповторяющиеся серии случайных чисел. Объект repeatRnd дает возможность повторить при необходимости серию. Метод NextDouble создает серию случайных чисел в диапазоне [0, 1). Вызываемый в цикле метод Next с двумя параметрами создает серию случайных отрицательных целых, равномерно распределенных в диапазоне [-100, -10]. Метод NextBytes объекта repeatRnd позволяет получить при одном вызове массив случайных чисел из диапазона [0, 255]. Результаты вывода можно увидеть на рис. 7.2.
(рис 7.2) Генерирование последовательностей случайных чисел в процедуре RandНа этом заканчивается рассмотрение темы выражений языка C#.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.