Никита Культин C# для начинающих

Глава 1. Введение в программирование

Язык программирования С#

Объектно-ориентированный язык программирования C# разработан в компании Microsoft в 1998—2001 годах группой инженеров под руководством Андерса Хейлсберга как средство разработки приложений для платформы Microsoft .NET Framework.

Синтаксис C# близок к синтаксису языков C++ и Java. Язык C# имеет статическую типизацию, поддерживает полиморфизм, перегрузку операторов, делегаты, атрибуты, события, свойства, обобщённые типы и методы, итераторы, анонимные функции с поддержкой замыканий.


Как научиться программировать на С#

Чтобы научиться программировать на том или ином языке, надо на этом языке программировать. Однако язык С#, вследствие своей объектной ориентированности а также того, что язык создавался как средство для профессионалов, является довольно сложным языком. Изучение объектно-ориентированных возможностей С# предполагает наличие довольно серьезной подготовки, опыта практического программирования. Так что же делать, не подступать к С# до тех пор пока не научишься программировать на другом, более доступном для новичка языке, например на Паскале? Ответ на этот вопрос подсказал, Бьярн Страуструп, создатель языка C++. Хотя Бьярн Страуструп говорит о C++, тем не менее его рецепт применим и к C#:

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

Основы

Программа

Программа, работающая на компьютере, зачастую отождествляется с самим компьютером, так как пользователь "вводит в компьютер" исходные данные (при помощи клавиатуры или мыши), а "компьютер выдает результат" на экран, на принтер или в файл. На самом деле ввод исходных данных, преобразование исходных данных в результат и вывод результата выполняет процессор. Процессор делает всю работу в соответствии с определенным алгоритмом, который будучи записан на специальном языке, называют программой. Таким образом, чтобы компьютер выполнил некоторую работу, необходимо составить последовательность команд, обеспечивающую выполнение этой работы, или, как говорят, написать программу.

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

Исходная программа представляет собой последовательность команд (инструкций) на языке программирования. Исходная программа это обычный текст. Исходная программа понятна человеку (программисту), но не понятна процессору, который может "понимать” (воспринимать, выполнять) только двоичный код.

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

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

Компиляция и интерпретация

Существует два подхода к выполнению программы: компиляция и интерпретация.

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

При интерпретации инструкции программы выполняет входящий в среду разработки интерпретатор. Программа, представленная на интерпретируемом языке программирования, может быть запущена только из соответствующей среды разработки. Примерами интерпретируемых языков являются Visual Basic for Application (VBA), Python а также язык R – специализированный язык статистической обработки данных.


Консольное приложение

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

По способу взаимодействия с пользователем различают оконные и консольные приложения.

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

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

В качестве примера на рис. приведен вид окна программы пересчета расстояния из миль в километры, реализованной как оконное Windows Forms приложение, а на рис. вид окна этой же программы, реализованной как консольное приложение.


Рис. . Оконное приложение


Рис. . Консольное приложение


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

Этапы разработки программы

Выражение "написать программу" отражает только один из этапов создания компьютерной программы, когда программист действительно пишет команды (инструкции на выбранном языке программирования) на бумаге или в редакторе среды разработки.

Программирование – это процесс создания (разработки) программы, который может быть представлен как последовательность следующих шагов:

*

Определение требований к программе

*

Разработка алгоритма решения задачи

*

Написание команд (кодирование)

*

Отладка

*

Тестирование

Определение требований к программе

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

Разработка алгоритма

На этапе разработки алгоритма необходимо определить последовательность действий, которые надо выполнить для достижения результата. Многие задачи можно решить различными способами. В этом случае программист, используя некоторый критерий, например, скорость работы алгоритма, выбирает наилучшее решение. Результатом этапа разработки алгоритма должен быть алгоритм, представленный в виде словесного описания или блок-схемы.

Кодирование

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

Отладка

Отладка – это процесс поиска и устранения ошибок. Ошибки в программе разделяют на две группы: синтаксические (ошибки записи инструкций) и алгоритмические.

Синтаксические ошибки проявляются в процессе компиляции программы. Они наиболее легко устраняемые. Алгоритмические ошибки обнаружить труднее. Этап отладки можно считать законченным, если программа правильно работает на одном-двух наборах входных данных.

Тестирование

Этап тестирования особенно важен, если вы предполагаете, что разрабатываемой программой будут пользоваться другие. На этом этапе следует проверить, как ведет себя программа на как можно большем количестве разнообразных входных наборов данных, в том числе и на заведомо неверных.

Алгоритм

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

Алгоритм – это точное предписание, определяющее процесс перехода от исходных данных к результату.

Алгоритмом должен обладать следующими свойствами:

*

однозначностью

*

массовостью

*

результативностью

Под однозначностью алгоритма понимается единственность толкования правил и порядка выполнения действий.

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

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

Алгоритм решения задачи может быть представлен в виде словесного описания или графически – в виде блок-схемы. Представление алгоритма в виде блок-схемы позволяет программисту уяснить последовательность действий, которые необходимо выполнить для решения задачи, убедиться в правильности понимания поставленной задачи.

В качестве примера на рис. приведена блок-схема алгоритма программы вычисления тока в электрической цепи состоящей из двух сопротивлений, которые могут быть соединены последовательно или параллельно. Обратите внимание, слова Начало и Конец внутри соответствующих символов нисать не следует; символы, соответствующие одинаковым типам действий должны быть одного размера; стрелки на ветвях, соединяющих элементы блок схемы, ставят, если процесс развивается справа налево или снизу вверх; в точке концентрация ветвей алгоритма рисуют точку.

Первая программа

Процесс создания программы на языке C# в Microsoft Visual Studio рассмотрим на примере консольного приложения, позволяющего посчитать средний вес, например, помидора в упаковке (рис. 1.0).


Рис. 1.0. Средний вес

Для того чтобы начать работу над новым консольным приложением на языке C# или, как принято говорить, над проектом, надо:

В меню Файл выбрать команду Создать проект.

В открывшемся окне Создание проекта раскрыть список Шаблоны / Visual C# и выбрать тип приложения – Консольное приложение Visual C# (рис. 1.1)

В поле Имя ввести название проекта и нажать кнопку OK.


Рис. 1.1. В окне Создание проекта надо выбрать тип приложения и задать имя проекта

В результате описанных действий будет создан проект – совокупность файлов, необходимых для создания выполняемого (exe) файла программы. Проект создается в папке проектов Visual Studio (по умолчанию это С:\Users\User\Documents\Visual Studio 2015\Projects\Project, где: User – имя пользователя в системе, Project – имя проекта, введенное в поле Имя.


Главное окно Microsoft Visual Studio в начале работы над новым проектом создания консольного приложения приведено на рис. 1.2. В его заголовке отображается имя проекта, над которым в данный момент идет работа.


Рис. 1.2. Окно среды разработки в начале работы над новым консольным приложением

Центральную часть окна Microsoft Visual Studio занимает окно редактора кода (текст программы программисты называют кодом), в котором находится сформированное средой разработки объявление класса программы. В заголовке окна редактора кода отображается имя файла (Program.cs), в котором находится код.


Программа

Структура программы

Программа на языке C# представляет собой объект Program.

В листинге 1 приведено объявление класса Program, сгенерированное средой разработки как результат активизации процесса создания нового консольного приложения.


Листинг 1.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;


namespace ConsoleApplication1

{

class Program

{

static void Main(string[] args)

{


}

}

}


Изначально класс Program содержит один единственный метод Main. Именно этот метод выполняется при запуске программы. Поэтому, в простейшем случае, инструкции, реализующие алгоритм программы, надо поместить в метод Main, между фигурными скобками, следующими за закрывающей скобкой, ограничивающей список параметров метода Main.


В листинге 2 приведено объявление класса Program приложения расчета среднего веса предмета (в дальнейшем, для краткости, вместо слов “объявление класса Program”, будем говорить “программа”).


Листинг 2. Средний вес

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;


namespace ConsoleApplication1

{

class Program

{

static void Main(string[] args)

{

double w = 0.0; // вес помидоров

int k = 0; // количество помидоров


double m = 0.0; // средний вес одного помидора


string st = "";


Console.Write("Общий вес (кг.) >");

st = Console.ReadLine();

w = System.Convert.ToDouble(st);


Console.Write("Количество (шт.) >");

st = Console.ReadLine();

k = System.Convert.ToInt32(st);


Console.WriteLine();


m = w / k;


String res = "Общий вес: " + w.ToString() + " кг. \n" +

"Количество: " + k.ToString() + " шт.\n" +

"–\n" +

"Средний вес: " + m.ToString() + " кг.\n\n";


Console.WriteLine(res);


Console.Write("Press any key to continue…");

int ch = Console.Read();


}

}

}


На примере программы Средний вес кратко рассмотрим некоторые инструкции языка C#.

Как было сказано, в простейшем случае, инструкции, реализующие алгоритм программы, находятся в методе Main. Инструкция

double w = 0.0;

это объявление переменной w. Слово double, стоящее перед именем переменной, показывает, что переменная w вещественная. После имени переменной стоит символ “присвоить” (в математике он называется “равно”) за которым следует вещественная константа 0.0 – ноль (черточка внутри овала позволяет различать букву О и цифру ноль). Это показывает, что переменной w присваивается начальное значение. Символ “точка с запятой” отмечает конец инструкции объявления переменной. Далее, одна за другой, следуют две наклонные черты, которые отмечают начало однострочного комментария, поясняющего, в рассматриваемом случае, назначение переменной w.

В следующей строке аналогичным образом объявляется целая переменная k (int – сокращение от integer, целое). Переменной k также присваивается начальное значение, которое задается целой константой.

Далее следуют объявления вещественной переменной m и строковой переменной st. Начальным значением переменной st является “пустая” (не содержащая ни одного символа), строка, т.к. после символа “присвоить” указана строковая константа, в которой между первой и второй двойными кавычками нет ни одного символа.

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

Первой выполняемой инструкцией программы является инструкция

Console.Write("Общий вес (кг.) >");

Не трудно догадаться, что она выводит на консоль, т.е. в окно, в котором работает программа, текст Общий вес (кг.) > и тем самым показывает пользователю, какую информацию он должен ввести.

Далее следует инструкция

st = Console.ReadLine();

В результате ее выполнения в переменную st записывается значение метода ReadLine – строка символов, которую пользователь набрал на клавиатуре. Надо понимать, что метод ReadLine возвращает именно строку символов, причем, даже в том случае, если строка будет содержать только цифры, все равно это строка, а не число.

Следующая инструкция

w = System.Convert.ToDouble(st);

присваивает значение переменной w, в качестве которого используется значение метода ToDouble, который преобразует значение строковой переменной st (в ней находится строка, введенная пользователем) в соответствующее вещественное число типа double. Обратите внимание, метод ToDouble вернет значение только в том случае, если строка, указанная в качестве его параметра, содержит правильное изображение вещественного числа. Правильной строкой для метода ToDouble является непустая строка, состоящая только из цифр (перед первой цифрой может находиться минус) и содержащая правильный десятичный разделитель – запятую (при стандартной для России настройке Windows).

Следующие три инструкции

Console.Write("Количество (шт.) >");

st = Console.ReadLine();

k = System.Convert.ToInt32(st);

обеспечивают ввод значения переменной k. Так как переменная k целого типа, то для преобразования строки, введенной пользователем, в целое значение используется метод ToInt32. Метод ToInt32 вернет значение только в том случае, если строка, указанная в качестве его параметра, содержит правильное изображение целого числа. Правильной строкой для метода ToInt32 является непустая строка, состоящая только из цифр (перед первой цифрой может находиться минус).

Инструкция присваивания

m = w / k;

вычисляет средний вес. Выполняется она так: значение переменной w делится на значение переменной k и полученный результат записывается в переменную m.

Следующая инструкция

String res = "Общий вес: " + w.ToString() + " кг. \n" +

"Количество: " + k.ToString() + " шт.\n" +

"–\n" +

"Средний вес: " + m.ToString() + " кг.\n\n";

формирует строку res, записывает в нее исходные данные и результат расчета. Строка res формируется путем конкатенации (объединения) строковых констант и преобразованных в строки значений численных переменных. Преобразование числа (значения числовой переменной) в строку выполняет метод ToString.

Следует обратить внимание на последовательности \n внутри строковых констант. Символ \ внутри строковой константы отмечает начало специальной последовательности символов. Последовательность \n трактуется как символ “новая строка”. Сами символы \n на экране не отображаются, но в результате их отправки в консоль курсор перемещается в начало следующей строки экрана.

Команда

Console.WriteLine(res);

выводит в окно консоли значение переменной res – исходные данные и результат расчета.

Далее следуют инструкции

Console.Write("Press any key to continue…");

int ch = Console.Read();

Они добавлены в конец для того, чтобы пользователь смог увидеть результат работы программы. Метод Read обеспечивает чтение символа с консоли, он ожидает нажатия клавиши и, после того как клавиша будет нажата, возвращает ее код. Таким образом обеспечивается приостановка выполнения программы до момента нажатия клавиши. Если рассматриваемых инструкций в конце программы не будет, то окно консоли закроется сразу после выполнения инструкции вывода результата и пользователь не сможет увидеть результат.

Запись программы

Инструкции программы записываются последовательно, одна за другой. После каждой инструкции ставится точка с запятой. Хотя в одной строке можно записать несколько инструкций, обычно каждую инструкцию программы пишут на отдельной строке.

Некоторые инструкции, например, инструкции выбора (if, switch), циклов (for, while), в соответствии с правилами хорошего стиля программирования записывают в несколько строк и для выделения логической структуры инструкции, используют отступы.

Для облегчения понимания логики работы программы в текст программы можно, и нужно, включать комментарии . Комментарий – это пояснительный текст, который игнорируется компилятором. Язык С# допускает два вида комментариев: однострочный и многострочный. Однострочный комментарий начинается двумя наклонными чертами и продолжается до конца строки, многострочный – с последовательности символов /* и продолжается до тех пор, пока в тексте программы не встретится последовательность */.

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

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

Набор программы

В процессе набора текста программы редактор кода автоматически выделяет цветом правильные элементы программы: ключевые слова языка программирования – синим, имена пространств имен – бирюзовым, строковые константы – коричневым, комментарии зеленым. Это позволяет уже на этапе набора контролировать правильность программы. Например, слово Console это имя пространства имен, содержащего методы работы с консолью, и оно выделяется бирюзовым. Если вместо Console набрать, например, Cansole, то в этом случае набранное слово будет отображено черным, должно насторожить программиста.

Редактор кода также выводит список объектов текущего пространства имен или свойств и методов текущего объекта, что позволяет не набирать полностью имена на клавиатуре, а выбрать нужное имя в списке. Например, если в окне редактора набрать System.Console и точку, то появится список свойств и методов объекта Console и программисту остается только выбрать нужное свойство или метод (рис. ). Обратите внимание, перед именами свойств отображается гаечный ключ, перед именами методов – кубик. Чтобы перейти к нужному элементу списка, надо нажать клавишу, соответствующую первому символу этого элемента, и нажать .


Рис. 1.23. Список методов и свойств объекта Console

После ввода имени метода и открывающей скобки редактор кода выводит подсказку о методе (рис. 1.22).


Рис. 1.22. Пример подсказки

Трансляция

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

Процесс создания выполняемого файла С# программы может быть представлен как последовательность этапов предварительной обработки, компиляции и компоновки (рис. ).

Рис. Процесс создания выполняемого файла

Препроцессор выполняет предварительную обработку исходной программы. Он просматривает текст исходной программы и выполняет директивы, которые в ней находятся (директива – инструкция, начинающаяся символом #). Если с исходной программе директив препроцессору нет, то обработка не выполняется и текст программы передается компилятору без изменений.

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

Если в программе нет синтаксических ошибок, то запускается процесс компоновки. Компоновщик собирает выполняемую программу – добавляет к сформированному компилятором коду код других модулей.

Чтобы активизировать процесс создания выполняемого файла, надо в меню Сборка выбрать команду Собрать решение. Если в программе ошибок нет, то в окно Вывод будет выведено сообщение об успешном завершении процесса сборки (рис . ).


Рис. Пример сообщения об успешной сборке программы

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


Рис. Пример сообщения о неуспешной сборке программы

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

Ошибки

Выполняемая программа (файл exe) создается только в том случае, если в исходной программе нет синтаксических ошибок. Если в программе есть ошибки, то программист должен их устранить. В табл. приведены некоторые сообщения о типичных ошибках.

Таблица.. Сообщения об ошибках


Сообщение

Возможная причина


Ошибка – Имя … не существует в текущем контексте

Используется необъявленная переменная или имя переменной в выражении не соответствует имени, указанному в инструкции объявления переменной. Например, в программе объявлена переменная sum, а в выражении указана переменная summ или Sum.


Предупреждение – Переменной … присвоено начальное значение, но оно не используется.

Переменная объявлена и ей присвоено начальное значение, но в программе она не используется или в выражении, где предполагается использование этой переменной, имя записано неправильно (в этом случае, скорее всего, помимо предупреждения будет выведено одно или несколько сообщений об использование несуществующего имени). Например, объявлена переменная Weight а выражении, в котором предполагается ее использование, вместо Weight написано weight


Процесс устранения ошибок носит итерационный характер. Обычно сначала устраняются наиболее очевидные ошибки, например, объявляются не объявленные переменные или если переменная объявлена, исправляются имена в выражениях, так, чтобы имена переменных в выражениях, соответствовали именам переменных в инструкциях объявления. Следует обратить внимание на то, что одна ошибка в программе может “тащить” за собой несколько других. Например, если в рассматриваемой программе вычисления среднего веса в инструкции объявления переменной w заменить w на W, то компилятор выведет сообщения о трех ошибках (так как в трех местах программы используется имя w) и предупреждение о неиспользуемой переменной W. Обратная замена W на w, т.е. одно исправление, устраняет три ошибки и предупреждение.

Запуск программы

Если в программе нет ошибок, то ее можно запустить. Сделать это можно несколькими способами: в меню Отладка выбрать команду Начать отладку или Запуск без отладки; сделать щелчок на кнопке Пуск (рис. ); нажать .


Рис. . Кнопка Пуск

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

Окно консоли, в котором работает программа вычисления среднего веса приведено на рис. . Обратите внимание, при вводе дробных значений в качестве десятичного разделителя введена запятая.


Рис. . Окно программы Средний вес

Исключения

Если в программе компилятор не выявил ошибок, это еще не значит, что программа будет всегда работать правильно. Например, если в программе Средний вес при вводе значения веса в качестве десятичного разделителя вместо запятой ввести точку, то после нажатия программа сначала ненадолго “задумается”, затем станет активным окно редактора кода, в котором будет выведено сообщение о возникновении исключения (ошибки, возникающие во время работы программы, называют исключениями; Exception – исключение), также будет выделена строка, содержащая команду, при выполнении которой исключение возникло (рис .).

Загрузка...