Theory and Tasks for Students - Spring 2019
Введение

C# (CSharp, Си-Шарп) - компилируемый язык программирования, созданный Microsoft. В основе языка лежит фреймворк .NET, предоставляющий доступ на высоком уровне абстракции к функционалу операционной системы, стандартным структурам данным и т.п. При компиляции программа переводится на специальный внутренний промежуточный язык CLI (Common Language Intermediate), что позволяет выполнить программу на любой машине, где установлен .NET Framework соответствующей версии или его заменитель, например, Mono для Linux.
В университете установлена среда разработки Visual Studio 2017, в которой и рекомендуется выполнять задания. В первом семестре нас интересуют консольные приложения, позже мы перейдём к оконным приложениям Windows Forms.

При создании консольного приложения среда разработки автоматически генерирует минимальный необходимый код, его не надо менять / удалять: using System; namespace ProjectName { class Program { static void Main(string[] args) { //---Ваш код должен быть здесь } } } // обозначает комментарий - вся оставшаяся строка не оказывает влияние на выполнение программы. Так же существует многострочный комментарий: /* ... */

Код можно писать по-разному, даже практически в одну строчку, однако это делает его нечитабельным. Некоторые распространённые правила написания красивого и понятного кода:

  • Знаки операций должны быть разделены пробелами
  • Название переменных должно отражать их назначение
  • Все название должны быть на английском языке
  • Каждая операция пишется на новой строке
  • Блоки кода, создаваемые парой фигурных скобок { ... } должны иметь отступ в 4 пробела
  • После { в строке не должно быть ничего, кроме комментариев
  • Строка с } может содержать только комментарий
  • Открывать блок кода { можно как и в конце строки сигнатуры метода, условного оператора и т.п., так и на новой строке

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

sbyte, short, int, long Целочисленные (integer) знаковые типы. Занимают 8, 16, 32, и 64 бит соответственно. Альтернативные названия - SByte, Int16, Int32, Int64. Диапазоны значений от -2N-1 до 2N-1-1, где N - количество бит. Чаще всего используется тип int, максимальное положительное значение которого равно 2147483647.
byte, ushort, uint, ulong Целочисленные беззнаковые (unsigned) типы. Занимают 8, 16, 32, и 64 бит соответственно. Альтернативные названия - Byte, UInt16, UInt32, UInt64. Диапазоны значений от 0 до 2N-1, где N - количество бит.
float, double Вещественные типы в плавающей точкой (floating point). Занимают 32 и 64 бита соответственно. Альтернативные названия - Single, Double. Точность до 7 и 15-16 знаков после запятой соответственно, т.к. хранят числа в экспоненциальном виде, например, 3.672+E221. Для точных вычислений обычно используется double. При записи чисел в формате float используется суффикс `f` - 2.733f.
decimal Вещественный тип с фиксированной точкой. Занимает 128 бит, хранит 28-29 значимых цифр. Альтернативное название - Decimal. При меньшем диапазоне значений и большей точности, по сравнению с типами с плавающей точкой, используется часто для финансовых расчётов. Числовые константы в этом типе должны иметь суффикс `m` - 2.733m.
bool Булевский (boolean) тип, переменные этого типа имеют одно из двух значений Булевой логики - true или false. Альтернативное название - Boolean.
char, string Символьный (character) и строковый типы. Отдельные элементы строки - символы, об этом будет рассказано чуть позже.
object, Random, void, int[], Form, StreamWriter и т.п. Все типы данных являются наследниками класса object - т.е. являются объектами. Как следствие, например, их все можно переводить в строковое представление. В качестве типа может выступать практически любой класс или структура, но подробности вы узнаете сильно позже, когда мы будем создавать свои типы.

Чтобы использовать переменную, её необходимо сначала описать / объявить (declare) следующим образом: тип_переменной имя_переменной;. Порядок строк в коде важен, т.к. он выполняется сверху вниз, т.е. вы не можете сначала записать значение в переменную, а потом объявить её. Для записи данных в переменную используется оператор присваивания =: int a; a = 2; double b; b = 1E-5; double bb = 0.00001; decimal dec = -10.001m; float alpha = a; string hello = "world", bye = "see you"; hello = "greetings";

Таким образом, слева от оператора присваивания должна быть переменная, а справа - выражение, значение которого будет записано в эту переменную. Как написано в блоке выше, можно описать переменную и присвоить ей значение в одной строке. Так же можно объявить несколько переменных одного типа через запятую. Нельзя создавать несколько переменных с одним именем - впрочем, тут тоже позже будут некоторые исключения. Тип значения выражения должен соответствовать типу переменной, в которою он будет записан, поэтому нельзя написать int a = 2.0;. Однако в некоторых случаях возможна смена типа значения без потери данных, например, double a = 2; - т.к. множество целых чисел является подмножеством вещественных чисел. Так же обратите внимание, что в конце каждой строки ставится символ ;.

В качестве выражения может выступать не одно значение или переменная, а формула, использующая математические операции и определённые функции, например, из класса Math: int a = 5 / 2; double b = 5.0 / 2; b = -Math.Pow(2, 3) / (a * 1E-9); int remainder = 5 % 2; Методы (функции) статического класса как Math вызывается через оператор . после имени класса.

+ - * ( ) Стандартные операции сложения, вычитания(и унарный минус) и умножения, а так же скобки. Действует привычный приоритет операций.
/ % Деление и остаток от деления (деление по модулю). При делении двух целых чисел производится целочисленное деление.
Math.Pow(x, y) Math.Cos(x) Math.Sqrt(x) Math.Log(x) ... Вовзведение в степень, косинус и многие другие математические функции класса Math.

Стандартные операции ввода/вывода - методы статического класса Console, доступного только в консольных приложениях: Console.ReadLine() и Console.WriteLine(str). Console.ReadLine() приостанавливает выполнение программы и ожидает пользовательского ввода - под этим понимается любая строка в консоли, оканчивающаяся символом перевода строки '\n', который ставится по нажатию `Enter`. Этот метод всегда возвращает строку, поэтому вместо int a = Console.ReadLine(); придётся написать string a = Console.ReadLine();. Чтобы считать эту строку как число необходимо воспользоваться классом Convert и его методами, например, Convert.ToInt32(str).

Console.WriteLine() выводит в консоль переданный ему аргумент, предварительно неявно конвертируя его в строку через метод object.ToString(), и добавляет символ перевода строки в конец. Если вызвать метод без аргументов, выведен будет лишь '\n'. Для вывода без этого символа существует метод Console.Write(). Для составления строк из частей (конкатенации) используется оператор +. Пример кода, считающий длину окружности и площадь круга с радиусом, введённым с клавиатуры: double r = Convert.ToDouble(Console.ReadLine()); double area = Math.PI * r * r; Console.WriteLine("Circumference = " + (2 * Math.PI * r).ToString()); Console.WriteLine("Area = " + area.ToString());

В конце выполнения программа обычно не останавливается, чтобы дать возможность посмотреть её вывод, т.к. консольные приложения преимущественно запускаются из командной строки или терминала. В Visual Studio можно выполнить программу с принудительной задержкой после завершения её работы с помощью комбинации клавиш Ctrl + F5. Альтернативно в конец программы можно вызвать метод, считывающий любую клавишу Console.ReadKey().