Уроки OpenGL + C#.

Краткие основы синтаксиса C# (в сравнении с С++).

Теперь мы кратко рассмотрим синтаксис C#, после чего перейдем к созданию собственных оконных приложений, и изучим методы работы с элементами окон, которая в несколько раз проще, удобнее и быстрее, чем разработка под MFC или чистый Win32 API. Как мы уже отметили, синтаксис языка C# крайне похож на С++. Не будем отказывать от традиций и создадим наше первое приложение – Hello World.
Для этого откройте редактор MS Visual Studio (все примеры будут проходить на MS Visual Studio 2008, SP1 с русскоязычным интерфейсом, который более понятен для начинающих программистов), хотя мы и рекомендуем использовать английскую версию.

Во избежание copy-past’ов (т.е. копирования готового кода непосредственно в программу) , все исходные коды будут отображаться на изображениях. Заполнение кода в Visual Studio стало крайне удобным, благодаря отлично реализованной системы подсказок, поэтому набор кода не должен составить никаких проблем ( вернее сказать даже вызывает привыкание :-) ). Запустите MS Visual Studio, после чего создайте новый проект, используя меню файл, как показано на рисунке 1.
Файл -> Создать -> Проект..


Создание нового проекта в MS Visual Studio 2008
Рисунок 1. Создание нового проекта.

Выберите проекты Visual C#, В шаблонах отметьте Консольное приложение и введите имя для нашего проекта : Hello World. По умолчанию все проекты сохраняются в папке
«Мои документы» текущего пользователя Visual Studio 2008Projects

Выбор типа создаваемого проекта, дирректории размещения и имени проекта.
Рисунок 2. Выбор типа проекта В открывшемся окне редактора будет код шаблона простейшего приложения .net на языке C#.

В него нам необходимо добавить 2 строки кода: первая будет выводить на экран сообщение Hello World, вторая будет ожидать строку, введенную пользователем, только после которой программа завершится. Ожидание ввода нам необходимо, что бы успеть прочитать вывод строки программой, иначе мы просто не успеем его увидеть – программа выполнит код и завершиться.


using
System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace HelloWorld
{
class Program
{

static void
Main(string[] args)
{
// выводим текст в консоль
System.Console.Write("Hello world again");

// ждем ввода строки от пользователя,
// после которого завершиться выполнение программы

String str = System.Console.ReadLine();
}
}
}


После того как вы набрали данный код, достаточно нажать F5 и подтвердить необходимость компиляции.
Программа будет запущена , после чего вы сможете увидеть результат ее работы (рисунок 3)


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

Теперь более подробно коснемся синтаксиса С#.   Объектно-ориентрованным языкам свойственно иметь две большие категории типов: типы которые присущи языку («базовые типы») и классы, которые программист может создать самостоятельно.

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

В .NET  и С# нет такой проблемы , т.к. любая сущность CTS (Common Type System – уникальная система типов, принятая в .NET) является объектом. Причем базовым классом является System.Object. Все типы в C# .NET делятся на РАЗМЕРНЫЕ

ТИПЫ и ССЫЛОЧНЫЕ ТИПЫ.

Размерные типы содержат реальные данные и следовательно не могут быть равны null.
Именование типов очень напоминает С++
Int , long, char,
За исключением того, что для беззнаковых чисел упрощено именование: теперь для этого используется первый символ “u” перед названием типа, вместо слова «unsigned» использовавшегося в С++.

На практике, написать uint намного удобнее, чем unsigned int.
Ссылочные типы крайне похожи на ссылки в С++. Правда, в отличи от указателя в С++, ссылочный тип гарантирует, что ссылка указывает на объект заданного типа в памяти, либо может быть равна null.
К примеру

 string str = “This is a test”;

Т.е., в данном случае, на практике было выделено место в памяти и str содержит ссылку на него.
Массивы и классы в C# являются ссылочными типами.
Типы и псевдонимы (с помощью которых, как правило происходит объявление)


СТS Тип
Имя псевдонима в С# Описание
System. Object object Класс , базовый для всех типов (CTS)
System. String string Строка
System. SByte sbyte 8 -разрядный байт (со знаком)
System. Byte byte 8 -разрядный байт (без знака)
System. Ы16 short 16-разрядное число (со знаком)
System. UM16 ushort 16-разрядное число (без знака)
System. Int32 int 32-разрядное число (со знаком)
System. UInt32 uint 32-разрядное число (без знака)
System. Int64 long 64-разрядное число (со знаком)
System. UInt64 ulong 64-разрядное число (без знака)
System.Char char 16-разрядный символ (Unicode)
System. Single float 32-разрядное число с плавающей точкой, (стандарт IEEE)
System. Double double 64-разрядное число с плавающей точкой, (стандарт IEEE)
System. Boolean bool Булевское значение (true/false)
System. Decimal

decimal

Данный 128 разрядный тип используется в основном, когда требуется крайне высокая точность (до 28 знака)

Теперь рассмотрим, как работает оператор ветвления, операторы выбора и как реализуются циклы

Оператор выбора (условный оператор IF).

Как известно, оператор выбора используется для последующего выполнения или не выполнения некоторого оператора или группы операторов, в зависимости от условия. Если предлагаемое условие истинно, то вложенный оператор или блок кода выполняется. Альтернативная ветвь, которая может присутствовать (а может и нет) выполниться, если условие ложно.

if (resault == 777)
{
System.Console.WriteLine("Congratulations, you win!!!!"); // выведет: «поздравляем, вы победили»
}
else
{
System.Console.WriteLine("please, try again "); // выведет: «пожалуйста, попробуйте снова»
System.Console.WriteLine("we are confident - you will be lucky"); //выведет: «мы уверены- вам повезет»
}

Так же, можно использовать упрощенный синтаксис, подобно С++ используя оператор ?:  (resault == 777) ? true : false ;  

Оператор ветвления

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


switch
( value )
{
default:
{
System.Console.WriteLine("для этого варианта действие не определено”);   
break;
}

case 1 :
{
System.Console.WriteLine("Цифра 1”);
break;
}

case 2 :
System.Console.WriteLine("Цифра 2”);
break; case 3 :
{
System.Console.WriteLine("Цифра 3”);          
break;
}
}

 

Так же, в языке С# существуют 4 вила циклов

Циклы реализуются с помощью следующих зарезервированных слов: while , do while , for , foreach .

Рассмотрим каждый на примере.

Примечание: переменные, объявленные в цикле (в том числе в заголовке цикла for и foreach) не видны снаружи цикла (так же как в стандартном C++). 1. Оператор цикла while. Пока истинно управляющее  условие,  выполняется оператор (или  тело цикла ). Пример: значение переменной a инициируется равным ста, затем пока а больше 5 выполняется тело цикла - вывод а, затем уменьшение его значения на 1.

int a = 100;
while (a > 5){
   System.Console.WriteLine(a);
   a--;
}


2. Оператор цикла do-while. В данном случае, тело цикла выполняется до проверки условия.

int a = 100;
do{
   System.Console.WriteLine(a);
  a--;
}while (a > 5)


3. Оператор цикла for. Цикл for  используют, как правило,  когда число повторений известно заранее, т.е. в задачах связанных с перебором. Мы устанавливаем начало отсчета, условие остановки, и тип изменения параметра.

Пример: перебор значения для a = 100 изначально, до тех пор пока a больше пяти. После каждого выполнения тела цикла, a уменьшается на единицу.

for (int a = 100; a > 5; a --)
{
   System.Console.WriteLine(a);
}


4. Оператор цикла foreach. Этот цикл полезен, когда необходимо перебрать все элементы массива, не вдаваясь в подробности :). Рассмотрим на примере : массив a состоит из 3 элементов. Цикл foreach перебер все значения имеющиеся в массиве, приравнивая их к переменной x. В теле цикла мы производим вывод этих значений.

int[] a = new int[]{1,2,3}; // наш массив 
foreach (int x in a)
{
   System.Console.WriteLine(x);
}

Как видно из кода, с массивами работать необходимо не совсем так, как в старом-добром С++.

Массивы.

Массивы претерпели изменения , по сравнению с синтаксисом языка С++.

Массивы в .NET имеют тип System.Array. Они не копируются при присваивании (т.е. это ссылки, а не значения). Так же , их можно использовать в циклах foreach. Свойство массива Length - содержит общее число элементов массива, что , кстати, очень удобно.

Одномерные массивы.

Да, начнем мы с одномерных массивов. Данный тип массива включает в себя информацию о базовом типом элементов, которые может содержать массив, а так же о количестве элементов в массиве (так называемая размерность массива). Нумерация элементов массивов, так же , как в языке С/C++, начинается с нуля.
Одномерные массивы определяются следующим образом:

uint[] arr_name = new uint[100];

Здесь arr_name - имя массива, 100 - количество элементов в массиве. Так как нумерация начинается с нуля, первый элемент доступен через следующее обращение - arr_name[0], последний: arr_name[99].

Теперь рассмотрим, как мы можем заполнить массивы значениями, а именно - три способа заполнения.

int arr_name = new int[2];
arr_name[0] = 1;
arr_name[1] = 2;
 
int[] arr_name = new int[] {1,2};
int[] arr_name = {1,2};

Прямоугольные массивы .

Прямоугольный массив - это ничто иное как двумерный массив , например размерностью 4 x 2:

int[,] arr_name_1 = new int[4,2]; 
int[,] arr_name_2 = {{0, 1, 2, 3}, {0, 1, 2}}; 
for(i = 0; i < arr_name_1.GetLength(0); i++){
   for (j = 0; j < arr_name_1.GetLength(1); j++)
   {
        System.Console.WriteLine(arr_name_1[i,j]);
   }
}


В данном коде мы рассмотрели пример вывода значений из двумерного массива.

 

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

Рассмотрим пример

public class MyTestClass
{
public  string SomeStringInformation;
}


C# имеет 4 модификатора доступа к элементам и методам класса:

Модификатор доступа Описание
public Член класса доступен вне определения класса и иерархии производных классов.
protected Член класса невидим за пределами класса и к нему могут обращаться только производные классы.
private Член класса недоступен за пределами области видимости определяющего его класса. Поэтому доступа к этим членам  нет даже у производных классов.
internal Член видим только в пределах текущей единицы компиляции. Модификатор доступа internals плане ограничения доступа является гибридом public и protected, который зависит от местоположения кода.



Безусловно, классы это очень обширная тема. Мы рассмотрим ее достаточно подробно, на примере разработки класса и реализации консольной работы с ним.
Данный материал представлен в следующей главе.  


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