Книги онлайн и без регистрации » Разная литература » Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»

Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 313 314 315 316 317 318 319 320 321 ... 415
Перейти на страницу:
смысл. С типами double корректная программа на C# может быть такой:

x =у;

Ь= (у! = 0);

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

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

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

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

x = x <operator> (expression)

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

x <operator>= expression

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

х += u+v; у /=(u-v);

b &= (х<у);

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

byte Ь3 = 21;

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

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

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

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

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

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

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

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

{an =i + 1; }

x+=an; z+=an; у = an;

string[] ars = new string[3];

doublet] 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]);

}

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

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

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

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

int x=3, y=5;

object obj1, obj 2;

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

obj1 = х; obj2 = у;

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

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

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

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

• обратные тригонометрические функции — ASin, ACcos, 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"):

               у = a*Math.Sin(b*t);

               break;

          case ("cos"):

              у = a*Math.Cos(b*t);

              break;

           case ("tan"):

               у = a*Math.Tan(b*t);

               break;

           case ("cotan"):

               у = a/Math.Tan(b*t);

               break;

            case ("In"):

1 ... 313 314 315 316 317 318 319 320 321 ... 415
Перейти на страницу:

Комментарии
Минимальная длина комментария - 20 знаков. В коментария нецензурная лексика и оскорбления ЗАПРЕЩЕНЫ! Уважайте себя и других!
Комментариев еще нет. Хотите быть первым?