Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

CSBasicCourse2ndedPodbelsky / CSBasicCourse2ndedPodbelsky

.pdf
Скачиваний:
35
Добавлен:
22.03.2016
Размер:
2.08 Mб
Скачать

последовательности цифр (возможно со знаком) передаётся в виде строки как аргумент методу Parse() класса int (иначе System.Int32). Задача метода сформировать код целого числа, которое станет значением переменной int res.

Особенность (и опасность) – в прочитанной строке не должно быть символов,

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

(проигнорированы). Например, строка может быть такой:

"- 240 "

Значением переменной res будет -240.

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

Для решения той же задачи чтения из входной строки целочисленного значения метод TryParse() можно применить так:

int res;

do Console.Write("Введите целое число: ");

while(int.TryParse(Console.ReadLine(),out res)==false);

В цикле с постусловием пользователю выводится приглашение "Введите целое число: ". Набранную на клавиатуре последовательность символов считывает метод

Console.ReadLine(). Возвращаемая методом строка служит первым аргументом метода TryParse() из класса int. Если строка является корректным изображением целого числа, то его код присваивается аргументу res, а метод TryParse() возвращает значение true. Тем самым цикл завершается. В противном случае параметр res

остаётся без изменений, метод TryParse() возвращает значение false, что приводит к следующей итерации цикла. Цикл будет повторяться, пока пользователь не введёт правильного изображения целого числа.

Методов преобразований для предопределённых типов в классе System.Convert

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

"преобразование строк в код" целого числа типа int предназначен метод:

Convert.ToInt32(строка);

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

генерируется исключение, и, если в программе не предусмотрена обработка этого исключения, программа завершается аварийно. Приведём пример с одним из

методов класса Convert:

string sPi = "3,14159", radius = "10,0";

double circle = 2 * Convert.ToDouble(sPi) * Convert.ToDouble(radius); Console.WriteLine("Длина окружности="+circle.ToString());

В примере определены две строки, содержащие изображения вещественных

чисел (типа double). Обратите внимание, что дробная часть строкового представления каждого числа отделена от целой части запятой, а не точкой. Это связано (как мы уже упоминали) с правилами локализации системы, в которой исполняется программа. В Европе и России целая и дробная части числа

традиционно разделяются запятой. В инициализаторе переменной double circle

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

Как догадался проницательный читатель, будет получено приближенное значение длины окружности с радиусом 10. В аргументе метода Console.WriteLine( ) явно выполнено (хотя это и не обязательно) преобразование значения circle к значению типа string. На консоль будет выведено:

Длина окружности=62,8318

(Опять запятая в изображении числа!)

8.10. Аргументы метода Main( )

До сего времени мы использовали вариант метода Main() без параметров.

Имеется возможность определять метод Main() с таким заголовком:

public static void Main (string [ ] arguments)

где arguments – произвольно выбираемое программистом имя ссылки на массив с

элементами типа string.

Эти элементы массива представляют в теле метод Main( ) аргументы

командной строки "аргумент: командной строки" . Конкретные аргументы

командной строки это разделённые пробелами последовательности символов,

размещённые после имени программы при её запуске из командной строки.

Если программа запускается не из командной строки, а из среды Visual Studio,

то для задания аргументов командной строки нужно использовать следующую

схему. В основном меню выбираете пункт Project, затем в выпадающем меню

выбираете команду имя_проекта Properties. В открывшемся окне на панели слева

(Application) выбираете закладку Debug. Справа открывается панель, одно из

текстовых полей которой названо

Command

line arguments. Текст, который

вводится в это поле, воспринимается как последовательность (разделённых

пробелами) значений аргументов метода Main(

). Как воспользоваться этими

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

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

сообщения об отсутствии аргументов в командной строке. Текст программы:

// 08_04.cs - Аргументы метода Main() using System;

class Program

{

static void Main(string[ ] numbs)

{

int sum = 0;

if (numbs.Length == 0)

{

Console.WriteLine("Нет аргументов в командной строке!"); return;

}

for (int i = 0; i < numbs.Length; i++) sum += Convert.ToInt32(numbs[i]);

Console.WriteLine("Сумма чисел = " + sum);

}

}

Результаты первого выполнений программы:

Командная строка: Program_1.e<ENTER>

Результат:

Нет аргументов в командной строке!

Результаты второго выполнений программы:

Командная строка: Program_1.e 24 16

-15<ENTER>

Результат:

Сумма чисел = 25

В теле метода Main() определена целочисленная переменная sum для подсчёта суммы. Параметр numbs – ссылка на массив ссылок на объекты типа string. Если при запуске программы в командной строке нет аргументов массив пуст, значение свойства numbs.Length равно нулю. Выводится сообщение "Нет аргументов в командной строке" и оператор return; завершает выполнение программы. При наличии аргументов, выполняется цикл for с параметром int i. (Можно применить и цикл foreach.) Строка очередной элемент массива numbs[i] – служит аргументом метода Convert.ToInt32(). Возвращаемое целочисленное значение увеличивает текущее значение переменной sum.

8.11. Неизменяемость объектов класса String

К символам объекта класса string, будь то объект, созданный компилятором для представления строки-литерала, или объект, созданный с помощью обращения к конструктору класса string, можно обращаться только для получения их значений.

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

с операцией индексирования [ ].

Чтобы "изменить" строку "изменение строки" , приходится прибегать к

"обходным маневрам". Например, можно переписать символы строки во

вспомогательный массив с элементами типа char. Элементы такого массива

доступны изменениям. Выполнив нужные преобразования, создадим на основе

изменённого массива новую строку, используя конструктор string (char[ ]). Если исходная строка не нужна можем присвоить её ссылке значение ссылки на полученный объект. Схема преобразованний показана на рис.8.2.

Рис. 8.2. Как изменить объект типа string

 

Последовательность операторов, соответствующая описанной схеме:

 

string row = "0123456789";

 

char[] rev;

 

rev = row.ToCharArray();

 

Array.Reverse(rev);

 

row = new string(rev);

 

Console.WriteLine(row);

 

Результат выполнения этого фрагмента программы:

 

9876543210

 

В примере определена ссылка row на объект класса

string,

инициализированный строковым литералом "0123456789". Определена без

 

инициализации ссылка rev на символьный массив. Затем к объекту, связанному со

ссылкой row, применён метод ToCharArray(), и результат присвоен ссылке rev.

Метод Reverse() класса Array меняет на обратный порядок размещения значений

элементов массива, связанного со ссылкой rev, использованной в качестве

аргумента. Из изменённого массива, адресованного ссылкой rev, конструктор

string( ) создаёт новую строку, ссылка на которую присваивается переменной row.

Тем самым разрывается связь ссылки row со строкой "0123456789", и row

связывается с объектом, содержащим последовательность "9876543210".

Контрольные вопросы

Объясните различия между регулярным и буквальным строковыми литералами. Каким образом в буквальный строковый литерал поместить символ кавычки? Перечислите способы создания объектов типа string.

Перечислите операции над строками.

Вчём особенность операции индексирования для строк?

Вчём отличия и в чём сходство строк и массивов типа char[ ]? Как выполняется операция присваивания для строк?

Какие операции сравнения применимы к строкам?

Перечислите особенности конкатенации строк со значениями других типов.

Вкаких случаях метод ToString() вызывается неявно?

Каково значение свойства Length для регулярного строкового литерала, содержащего эскейп-последовательности?

Как выполняется сравнение строк? Как выполняется метод Join()? Как выполняется метод Split()?

Объясните правила применения метода Format().

Назовите назначения элементов поля подстановки строки форматирования. Перечислите спецификаторы формата поля подстановки.

Какой тип должна иметь переменная цикла foreach, применяемого к строке? Как инициализировать массив строк?

Как получить строку, символы которой представляют значение типа long?

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

Как при запуске программы задать аргументы?

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

Глава 9. Методы C#

9.1. Методы–процедуры и методы-функции

Как писал Никлаус Вирт, программы это алгоритмы + структуры данных.

Можно считать, что данные в C# – это поля объектов и статические поля классов.

Алгоритмы (то есть функциональность программ) представляются с помощью методов класса и методов его объектов. В языке C# методы не существуют вне классов. Нестатические методы реализуют функциональность объектов.

Статические методы обеспечивают функциональность классов и, тем самым,

программы в целом.

Для определения методов и при их вызове в C# не используются никакие служебные слова. В "языках древности", таких как ФОРТРАН или КОБОЛ, и в некоторых более современных языках, не входящих в семейство Си-образных, для обозначения подпрограмм, функций, процедур используются специальные термины,

включаемые в список служебных слов соответствующего языка. (FUNCTION, SUBROUTINE – в Фортране, procedure в Паскале и т.д.). Для вызова подпрограмм в Фортране используется конструкция со служебным словом CALL и т.п.

В языках, ведущих своё происхождение от языка Си (С++, Java, C# и др.) при определении функций и для обращения к ним специальные термины не применяются. Это в полной мере относится и к методам языка C#. Однако синтаксически и семантически методы C# можно разделить на процедуры

"процедуры" и функции "функции" . Это деление не особенно жёсткое и в ряде случаев метод может играть две роли и процедуры и функции.

В упрощённом варианте формат декларации метода, который может играть

роль как процедуры, так и функции, можно представить так:

модификаторы_методаopt

тип_возвращаемого_значения имя_метода (спецификация_параметров) { операторы_тела_метода }

Индекс opt указывает на необязательность модификаторов метода.

Фигурные скобки ограничивают тело метода "метод:тело метода" , часть

объявления перед телом метода называют заголовком метода "метод:заголовок метода" .

Минимальная конструкция, применяемая для обращения к методу:

имя_метода(список_аргументов).

В общем случае имя метода при обращении дополняется префиксами,

указывающими на принадлежность метода пространству имён, конкретному классу или реально существующему объекту.

Метод–процедура "метод:методпроцедура" отличается от методафункции следующими свойствами:

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

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

(из метода) расположена за последним оператором тела метода.

Для обращения к методу-процедуре используется только оператор вызова метода:

имя_метода (список_аргументов);

Метод–функция "метод:методфункция" :

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

Втеле функции всегда присутствует, по крайней мере, один оператор возврата:

return выражение;

Выражение определяет возвращаемый функцией результат.

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

согласования операндов в выражении по типам.

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

имя_метода (список_аргументов);

В этом случае функция выступает в роли процедуры.

Когда вы знакомитесь с некоторым методом (или пишете свой метод), очень важно понимать, откуда метод берёт (или будет брать) исходные данные и куда (и

как) метод отправляет результаты своей работы.

Исходные данные могут быть получены:

Через аппарат параметров метода;

Как глобальные по отношению к методу;

От внешних устройств (потоки ввода, файловые потоки).

Результаты метод может передавать:

Вточку вызова как возвращаемое значение;

Вглобальные по отношению к методу объекты;

Внешним устройствам (потоки вывода, файловые потоки);

Через аппарат параметров метода.

Глобальными по отношению к методу объектами в C# являются статические поля класса, в котором, метод определён, и поля (статические) других классов,

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

Обмены со стандартными потоками ввода-вывода, поддерживаемые средствами класса Console, нам уже знакомы. Для организации обменов с файловыми потоками

используются те средства библиотеки классов, которые мы ещё не рассматривали.

Сосредоточимся на особенностях обменов через аппарат параметров.

При определении метода в его заголовке размещается спецификация параметров "параметр:спецификация параметров" (возможно пустая) –

разделённая запятыми последовательность спецификаторов параметров. Каждый спецификатор имеет вид:

модификатор тип_параметра имя_параметра

Модификатор параметра может отсутствовать или имеет одну из следующих

форм: ref, out, params.

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

предопределённого типа (базовые типы, строки, object); перечислением;

структурой; классом; массивом; интерфейсом; делегатом.

Имя параметра это идентификатор, который выбирает программист автор метода. Область видимости и время существования параметра

ограничиваются заголовком и телом метода. Таким образом, параметры не видны и недоступны для кода, который не размещён в теле метода.

Стандарт C # отмечает существование четырёх видов параметров

"параметр:вид параметра" :

 

параметры, передаваемые по значениям

"параметр:параметры, передаваемые по

значениям" ;

 

параметры, передаваемые по ссылкам

"параметр:параметр передаваемый по

ссылкам" (ref);

 

выходные параметры "параметр:выходные параметры" (out);

массив-параметр "параметр:массив-параметр" (params).

Параметры первых трёх видов в Стандарте C# называют фиксированными параметрами. Спецификация фиксированного параметра включает необязательный модификатор ref или out, обозначение типа и идентификатор (имя параметра).

Список параметров представляет собой, возможно пустую, последовательность

Соседние файлы в папке CSBasicCourse2ndedPodbelsky