Теоретические сведения

Среда разработки Visual Studio.Net - это уже проверенный временем программный продукт, являющийся седьмой версией Студии. Но новинки этой версии, связанные с идеей.Net, позволяют считать ее принципиально новой разработкой, определяющей новый этап в создании программных продуктов. Выделю две важнейшие, на мой взгляд, идеи:

  • открытость для языков программирования;
  • принципиально новый подход к построению каркаса среды - Framework.Net.

Среда разработки теперь является открытой языковой средой. Это означает, что наряду с языками программирования, включенными в среду фирмой Microsoft - Visual C++.Net (с управляемыми расширениями), Visual C#.Net, J#.Net, Visual Basic.Net, - в среду могут добавляться любые языки программирования, компиляторы которых создаются другими фирмами-производителями. Таких расширений среды Visual Studio сделано уже достаточно много, практически они существуют для всех известных языков - Fortran и Cobol, RPG и Component Pascal, Oberon и SmallTalk. Открытость среды не означает полной свободы. Все разработчики компиляторов при включении нового языка в среду разработки должны следовать определенным ограничениям. Главное ограничение, которое можно считать и главным достоинством, состоит в том, что все языки, включаемые в среду разработки Visual Studio.Net, должны использовать единый каркас - Framework.Net. Благодаря этому достигаются многие желательные свойства: легкость использования компонентов, разработанных на различных языках; возможность разработки нескольких частей одного приложения на разных языках; возможность бесшовной отладки такого приложения; возможность написать класс на одном языке, а его потомков - на других языках. Единый каркас приводит к сближению языков программирования, позволяя вместе с тем сохранять их индивидуальность и имеющиеся у них достоинства. Преодоление языкового барьера - одна из важнейших задач современного мира. Благодаря единому каркасу, Visual Studio.Net в определенной мере решает эту задачу в мире программистов.

В каркасе Framework.Net можно выделить два основных компонента:

  • статический - FCL (Framework Class Library) - библиотеку классов каркаса;
  • динамический - CLR (Common Language Runtime) - общеязыковую исполнительную среду.

Понятие каркаса приложений - Framework Applications - появилось достаточно давно; по крайней мере, оно широко использовалось еще в четвертой версии Visual Studio. Важна роль библиотеки классов MFC (Microsoft Foundation Classes) как каркаса приложений Visual C. Несмотря на то, что каркас, первоначально был представлен только статическим компонентом, уже тогда была очевидна его роль в построении приложений. Уже в то время важнейшее значение в библиотеке классов MFC имели классы, задающие архитектуру строящихся приложений. Когда разработчик выбирал один из возможных типов приложения, например, архитектуру Document-View, то в его приложение автоматически встраивались класс Document, задающий структуру документа, и класс View, задающий его визуальное представление. Класс Form и классы, задающие элементы управления, обеспечивали единый интерфейс приложений. Выбирая тип приложения, разработчик изначально получал нужную ему функциональность, поддерживаемую классами каркаса. Библиотека классов поддерживала и более традиционные для программистов классы, задающие расширенную систему типов данных, в частности, динамические типы данных - списки, деревья, коллекции, шаблоны.

Обьявление и инициализация переменных:

 

Тип_переменной имя_переменной [=значение];

Примеры:

int x; //обьявление переменной x

x=100; //инициализация переменной x

long w,z=100; //обьявление переменных w и z и

         //инициализация z

long q=100*z; //обьявление переменной с динамической

         //инициализацией

Декларация классов, функций и переменных на уровне класса требует указания модификатора доступа. Впрочем, если не указывать, то будет использован стандартный модификатора, обычно private. Модификаторы доступа - это ключевые слова, определяющие, откуда можно будет получить доступ к декларированной переменной/функции и пр. Их всего несколько:

private - доступ возможен только изнутри класса, в котором объявлена.

protected - дос­туп воз­мо­жен из это­го клас­са и всех нас­лед­ни­ков.

internal - дос­туп воз­мо­жен из всей as­sembly (сбор­ки/биб­ли­оте­ки, фай­ла ко­ро­че). Так­же при­ме­ня­ет­ся для клас­сов, enum и ин­тер­фей­сов.

public - дос­туп воз­мо­жен от­ку­да угод­но. Так­же при­ме­ня­ет­ся для клас­сов, enum и ин­тер­фей­сов.

Есть еще мо­ди­фи­ка­то­ры сос­то­яния, оп­ре­де­ля­ющие прин­ци­пи­аль­ное сос­то­яние фун­к­ций­:

static - фун­к­ция ста­тич­на, т.е. воз­мож­но ее ис­пол­не­ние без соз­да­ния объ­ек­та клас­са. Нап­ри­мер, фун­к­ции клас­са System.Math - ста­тич­ные, пос­коль­ку вы­пол­ня­ют­ся прос­тым вы­зо­вом, без соз­да­ния объ­ек­та клас­са Math. Так­же при­ме­ня­ет­ся для клас­сов, тог­да все вхо­дя­щие в не­го фун­к­ции и пе­ре­мен­ные дол­ж­ны быть sta­tic.

abstract - фун­к­ция толь­ко дек­ла­ри­ро­ва­на, а оп­ре­де­ле­ние фун­к­ции дол­ж­но быть в клас­сах нас­лед­ни­ках. Ис­поль­зу­ет­ся для соз­да­ния шаб­ло­на клас­са, все нас­лед­ни­ки ко­то­ро­го обя­за­тель­но име­ют не­кий на­бор фун­к­ций. Мо­жет су­щес­т­во­вать толь­ко в ab­s­t­ract клас­се. Так­же при­ме­ня­ет­ся для клас­сов.

virtual - фун­к­цию мож­но пе­ре­оп­ре­де­лить в клас­се нас­лед­ни­ке.

override - ис­поль­зу­ет­ся для ука­за­ния, что опи­сы­ва­емая фун­к­ция пе­ре­оп­ре­де­ля­ет ро­ди­тель­с­кую.

Модификатор дос­ту­па для фун­к­ции/пе­ре­мен­ной внут­ри клас­са не мо­жет быть бо­лее дос­туп­ным, не­же­ли мо­ди­фи­ка­тор дос­ту­па все­го клас­са.

Переменные, дек­ла­ри­ру­емые внут­ри фун­к­ций мо­ди­фи­ка­то­ра дос­ту­па не тре­бу­ют.

Декларация пе­ре­мен­ных обя­за­тель­но сос­то­ит из ти­па дан­ных и име­ни, ос­таль­ное - по си­ту­ации и же­ла­нию.

Примеры дек­ла­ра­ций пе­ре­мен­ных:

 

int i;

public do­ub­le myDo­ub­le1, myDo­ub­le2;

internal sta­tic System.String con­st_string = "кон­с­тан­та";

 

Декларация фун­к­ций обя­за­тель­но сос­то­ит из ти­па воз­в­ра­ща­емых дан­ных, име­ни и спис­ка ар­гу­мен­тов, ос­таль­ное - по си­ту­ации. Воз­ра­ща­емым ти­пом дан­ных мо­жет быть vo­id - пус­той - т.е. нет воз­в­ра­ща­емых дан­ных. Спи­сок ар­гу­мен­тов то­же мо­жет быть пус­тым. Фун­к­ции, в от­ли­чии от пе­ре­мен­ных, не мо­гут быть толь­ко дек­ла­ри­ро­ва­ны - они обя­за­тель­но сра­зу оп­ре­де­ля­ют­ся. Един­с­т­вен­ное ис­к­лю­че­ние - тип фун­к­ций ab­s­t­ract, они толь­ко дек­ла­ри­ру­ют­ся, а оп­ре­де­ля­ют­ся уже в клас­сах нас­лед­ни­ках.

Здесь следует учитывать важное обстоятельство! CLR не допускает использования в выражениях неинициализированных локальных переменных. В C# к таковым относятся переменные, объявленные в теле метода. Так что при разработке алгоритма следует обращать на это особое внимание.

Константы. Объявляются с дополнительным спецификатором const. Требуют непосредственной инициализации. В данном примере инициализируется литералом 3.14.

const float Pi = 3.14.

C# - язык со строгим контролем типов данных. Есть 2 основные категории встроенных типов данных в C# - простые типы и ссылочные типы. Основные простые типы данных в C# приведены в таблице 1.

Область видимости переменной в C# - блок кода (заключенный в фигурные скобки {}). Переменная создается при входе в область видимости, и уничтожаются при выходе из нее.

Если используются длинные имена, то вы должны писать System.Int32 для типа int и т. п. (т. е. приписывать слово System перед CLR-именем). Или же вы должны добавить строчку using System;

Таблица 1.

Основные простые типы данных в C#

Логический тип

Имя типа Системный тип

Значения

Размер
Bool System.Boolean

true, false

8 бит

Арифметические целочисленные типы

Имя типа Системный тип

Диапазон

Размер
Sbyte System.SByte

-128 — 127

Знаковое, 8 Бит
Byte System.Byte

0 — 255

Беззнаковое, 8 Бит
Short System.Short

-32768 —32767

Знаковое, 16 Бит
Ushort System.UShort

0 — 65535

Беззнаковое, 16 Бит
Int System.Int32

≈(-2*10^9 — 2*10^9)

Знаковое, 32 Бит
Uint System.UInt32

≈(0 — 4*10^9)

Беззнаковое, 32 Бит
Long System.Int64

≈(-9*10^18 — 9*10^18)

Знаковое, 64 Бит
Ulong System.UInt64

≈(0— 18*10^18)

Беззнаковое, 64 Бит

Арифметический тип с плавающей точкой

Имя типа Системный тип

Диапазон

Точность
Float System.Single

+1.5*10^-45 - +3.4*10^38

7 цифр
Double System.Double

+5.0*10^-324 - +1.7*10^308

15-16 цифр

Арифметический тип с фиксированной точкой

Имя типа

Системный тип

Диапазон

Точность
Decimal

System.Decimal

+1.0*10^-28 - +7.9*10^28

28-29 значащих цифр

Символьные типы

Имя типа

Системный тип

Диапазон

Точность
Char

System.Char

U+0000 - U+ffff

16 бит Unicode символ

String

System.String

Строка из символов Unicode

Объектный тип

Имя типа

Системный тип

Примечание

Object

System.Object

Прародитель всех встроенных и пользовательских тип

           

Таким образом, следующие три объявления переменной k равносильны:

int k;

using System;

...

Int32 k;

и

System.Int32 k;

Разумеется, аналогично мы имеем дело и другими типами языка C#.

Объявление переменной можно совместить с инициализацией (заданием начального значения):

int z=88;

Набор операторов для C# достаточно стандартен +, -, *, / - действуют как и в любом другом языке. Отметим только, что / (деление) применительно к целым числам дает целую часть от деления. Так, фрагмент

int k=100999, n=1000, s;

s=k/n;

Console.WriteLine(s.ToString());

выведет на экран 100, а не 101, т. е. никакого округления не происходит.

Есть еще один оператор - %. Это - остаток от деления. Следующий фрагмент выведет на экран 999:

int k=100999, n=1000, s;

s=k%n;

Console.WriteLine(s.ToString());

Как и в других C-подобных языках, в C# существуют операторы инкремента и декремента. Так, после следующего фрагмента k увеличится на 1, а n - уменьшится на 1, т.е.  реализуются выражения k=k+1, n=n-1:

k++;

n--;

Пример программы сложения двух чисел на листинге 1.

Листинге 1.

//Использовать пространство имен System необходимо

using System;

//Класс реализующий сложение двух чисел

class Class1

{

//Объявляем переменные, которые мы будем складывать

private int x, y;

//Конструктор, который присваивает значения переменным    

public Class1(int intX, int intY)

{

       x=intX;

       y=intY;

}

//Функция, которая складывает два числа и

   // выводит результат на экран

public void Add()

{

       Console.WriteLine("Result: {0}",x+y);

}

}

//Класс, в котором расположена точка входа

class Class2

{

//А вот и сама точка входа - функция Main

//В качестве параметров передаются параметры

//командной строки

public static void Main(string[] args)

{

//Создаем экземпляр класса Class1

//Одновременно присваивая значения переменным

Class1 ex = new Class1(Int32.Parse(args[0]), Int32.Parse(args[1]));

//Складываем два числа и выводим

//результат на экран

ex.Add();

}

}

Проанализируем данное решение. Создали два класса: Class1 и Class2. В данной задаче, можно было бы воспользоваться и одним классом, но использование двух классов для данной задачи предпочтительно, для лучшего понимания структуры. Собственно вся работа ложится на плечи класса Class1, который и реализует главную задачу - сложение двух чисел.

Давайте подробно рассмотрим класс Class1. Все классы должны иметь строгую структуру. Подробнее о классах будет говориться в других лабораторных работах. Ее можно представить так:

class Class1

{

// Здесь располагаются свойства,

   // методы данного класса и другие члены

}

Кстати, зеленным цветом выделены комментарии (обратите внимание на их оформление). Они необходимы только для вас и для тех, кто будет изучать ваш исходный код. Компилятор игнорирует комментарии, как будто их и нет. Использование комментариев никогда не бывает лишним. Старайтесь их использовать во всех ваших приложениях.

В этом же классе объявляются две переменные x и y, которые будут складываться.

private int x,y;

Слово private необходимо для того, чтобы к этим переменным нельзя было обращаться напрямую из других классов.

Ключевое слово int означает, что обе переменные будут целочисленными. В .NET существует множество встроенных типов. Число данного типа может лежать в диапазоне от -2147483648 до 2147483648. Для данной задачи данного диапазона вполне хватит. После объявления создается новый конструктор:

public Class1(int intX, int intY)

{

       x=intX;

       y=intY;

}

Конструктор - это особая функция, которая автоматически вызывается при создании экземпляра данного класса. Конструктор называется точно также как и сам класс, в котором он находится: Class1. Конструкторы необходимы для того чтобы произвести начальную настройку объекта при его создании, чтобы в дальнейшем этим не заниматься. Конструкторов у одного класса может быть бесчисленное множество. И у каждого класса есть по крайней мере один конструктор. Этот конструктор называется конструктором по умолчанию, при вызове данного конструктора всем объектам данного класса присваиваются значения по умолчанию, например 0. Чуть позже мы рассмотрим работу конструктора по умолчанию. Этот конструктор в описании не нуждается, он создается автоматически. Понятно, что в нашем классе он так же есть, т.е. в нашем классе имеется два конструктора.

В качестве параметров нашему конструктору передаются два параметра intX и intY. Такое название этим переменным я придумал сам, вы же может придумать свои названия. После чего переменным x и y присваиваются значения intX и intY соответственно. Это означает, что после операции x=intX переменная x будет равна intX, а после операции y=intY переменная y будет равна переменной intY.

После создания конструктора мы написали функцию Add(), которая выполняет сложение двух чисел.

public void Add()

{

       Console.WriteLine("Result: {0}",x+y);

}

При этом выполняется условие задачи. Данная функция не получает ни каких параметров. Вместо нее это делает конструктор. Сложение чисел и вывод их на экран делается в нашем случае одним оператором, хотя можно было бы сделать и двумя.

Обратите внимание на ключевое слово void. Любая функция может возвращать какое либо значение. Не исключением является и функция Add(). Слово void означает, что наша функция не будет возвращать никаких значений, нам это не нужно. Если бы нам потребовалось, чтобы Add() возвращала какое-либо значение после своего завершения, а следовательно и завершения приложения, мы бы написали вместо void название какого-либо типа, например int.

А вот как может выглядеть функция, которая возвращает значение:

public int Add()

{

       return x+y;

}

Команда return возвращает значение функции, в нашем случае это значение выражения x+y и это значение типа int.

Функция WriteLine из пространства имен Console выводит строку на экран. Обратите внимание на то, как вызывается эта функция: Console.WriteLine. Если написать просто WriteLine, то компилятор вернет ошибку: "The name ′WriteLine′ does not exist in the class or namespace ′Class1′", т.е. такого метода не существует.

В качестве параметров функции WriteLine передается следующая строка "Result: {0}",x+y. В данной строке две части (их может быть бесчисленное множество). В начале считается выражение x+y. После этого на экран выводится текст, находящийся между кавычек, при этом вместо {0} автоматически подставиться результат операции x+y.

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

Вот простой пример: После операции:

Console.WriteLine("{0}{1}",x+y, x-y);

На экран будет выведен через пробел результат сложения и вычитания. В данном случае x+y - это нулевое выражение (отсчет в C# практически всегда начинается с 0), а x-y - это первое выражение. Надеюсь, что это вы усвоили, т.к. эти символы будут использоваться нами неоднократно.

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

{0:C} - денежный формат. Например число 19722.345 преобразуется в 19 722,35р. (Это зависит от того какой денежный формат установлен у вас в системе);

{0:D6} - фиксированное поле. Вместо шестерки можно подставить любое другое число, равное ширине поля. Например, при данном параметре число 457 преобразуется в 000475;

{0:E} - экспоненциальная форма;

{0:F4} - очень важный параметр, вместо четверки можно подставить любое число равное количеству символов после запятой, например число 3.234567 преобразуется в 3.2346.

Один из классов написан. Приступаем к написанию второго.

Второй класс называется Class2. В данном классе есть всего лишь одна функция Main (обязательно с заглавной буквы). Эта функция особенная. Она есть в любом приложении. Это и есть та самая входная точка. Именно с этой функции начинается работа приложения. Общий вид нашей функции Main имеет вид:

public static void Main(string[] args)

{

Class1 ex = new Class1(Int32.Parse(args[0]),Int32.Parse(args[1]));

ex.Add();

}

Слово static означает, что эта функция будет доступна тогда, когда ни создано еще не одного экземпляра класса. Мы ведь вообще не создаем экземпляр класса Class2. Если мы уберем слово static, то компилятор выдаст сообщение о том, что у нашей программы нет точки входа, т.е. она не доступна. У нашей функции Main есть параметр: string[] args.

Это массив параметров командной строки. Массив - это совокупность некоторых данных. О том, что это именно массив, говорят квадратные скобки. Слово string означает, что наш массив будет состоять из элементов типа string. Args - это название нашего массива, название можно придумать любое. В принципе у функции Main других параметров быть и не может. Рассмотрим следующую строку, в ней есть много интересного:

Class1 ex = new Class1 (Int32.Parse (args[0]), Int32.Parse (args[1]));

Итак, этой командой создается экземпляр класса Class1 (об этом говорит первое слово), который называется ex (название можно выбрать любое). Ключевое слово new означает, что создается новый объект. Далее вызывается конструктор. Там два параметра intX и intY. В данном случае эти переменные будут равны Int32.Parse(args[0]) и Int32.Parse(args[1]) соответственно. Т.е. вместо intX будет подставлен первый параметр командной строки (об этом говорит цифра 0. В C# отсчет ведется с нуля.), а вместо intY будет подставлен второй параметр. Конструкция Int32.Parse() необходима для преобразования типов. Ведь переменные intX и intY имеют тип int, а элементы массива args имеют тип string, поэтому надо преобразовать string в int. Именно это и делает функция Int32.Parse(). И, наконец, последняя команда вызывает функцию Add() класса Class1. Эта функция складывает две переменные и выводит результат на экран.

Давайте подведем итог. Итак, мы создали класс, в котором есть функция Add(), две переменные и дополнительный конструктор. В основной функции Main создается объект ex (экземпляр класса Class1), после этого о классе можно забыть, уже работаем с объектом, у которого есть свои свойства и методы. Одним из таких методов является функция Add(), которая вызывается.

Операторы языка

Операторы срав­не­ния:

< - стро­го мень­ше. Оп­ре­де­лен для лю­бых чис­ло­вых ти­пов (int, do­ub­le, short, byte, de­ci­mal, flo­at, bo­ol)

> - стро­го боль­ше. Ана­ло­гич­но пре­ды­ду­ще­му.

<= - мень­ше или рав­но. Ана­ло­гич­но пре­ды­ду­ще­му.

>= - боль­ше или рав­но. Ана­ло­гич­но пре­ды­ду­ще­му.)

== - рав­но (экви­ва­лен­т­но). Оп­ре­де­лен для боль­шин­с­т­ва ти­пов и клас­сов. Для мно­гих клас­сов оз­на­ча­ет имен­но иден­тич­ность объ­ек­тов клас­са, а не ра­вен­с­т­во их внут­рен­них зна­че­ний.

!= - не рав­но. Ана­ло­гич­но пре­ды­ду­ще­му.

Обратите вни­ма­ние: про­вер­ка на ра­вен­с­т­во обоз­на­ча­ет­ся дву­мя зна­ка­ми рав­но! Од­ним зна­ком обоз­на­ча­ет­ся опе­ра­тор прис­во­ения зна­че­ния.

 

Логические опе­ра­то­ры:

|| - ло­ги­чес­кое ИЛИ.

&& - логическое И.

! - ло­ги­чес­кое НЕ.

 

Арифметические опе­ра­то­ры:

помимо стан­дар­т­ных +, -, *, / есть их мо­ди­фи­ка­ции со зна­ком рав­но: +=, -=, *=, /=. Оз­на­ча­ют "вы­пол­нить опе­ра­тор и при­рав­нять", т.е.

i += 10;

означает при­ба­вить 10 к зна­че­нию пе­ре­мен­ной i, и за­пи­сать ре­зуль­тат в нее же. Это ана­ло­гич­но за­пи­си:

i = i + 10;

есть еще два опе­ра­то­ра:

++ - при­ба­вить еди­ни­цу к пе­ре­мен­ной и за­пи­сать ре­зуль­тат в нее. Ин­к­ре­мен­т­ный опе­ра­тор.

-- - от­нять еди­ни­цу от зна­че­ния пе­ре­мен­ной и за­пи­сать ре­зуль­тат в нее. Дек­ре­мен­т­ный опе­ра­тор.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: