Прочитав эту главу, вы научитесь:
• обновлять значение переменной с использованием операторов составного присваивания;
• записывать инструкции while, for и do;
• останавливать программу в ходе выполнения инструкции do и наблюдать за изменением значений переменных.
Из главы 4 «Использование инструкций принятия решений» вы узнали, как для выборочного запуска инструкций используются конструкции if и switch. В этой главе вы узнаете, как использовать различные инструкции итераций (или циклов) для повторных запусков одной или нескольких инструкций.
При запуске инструкций итераций требуется, как правило, средство управления количеством выполненных итераций. Этого можно достичь с помощью переменных, обновления при выполнении каждой итерации и остановки процесса по достижении переменной конкретного значения. Чтобы упростить этот процесс, начнем с изучения специальных операторов присваивания, которые будут использоваться для обновления значения переменной в подобных обстоятельствах.
Порядок использования арифметических операторов для создания новых значений вам уже известен. К примеру, в следующей инструкции для вывода на консоль значения на 42 единицы больше значения переменной answer используется оператор «плюс» (+):
Console.WriteLine(answer + 42);
Вы также знаете, как для изменения значения переменной используются операторы присваивания. В следующей инструкции для изменения значения answer на 42 используется оператор присваивания (=):
answer = 42;
Если нужно прибавить 42 к значению переменной, можно использовать сочетание оператора присваивания и оператора +. Например, в следующей инструкции к answer добавляются 42 единицы. После запуска этой инструкции значение answer становится на 42 единицы больше, чем было до того:
answer = answer + 42;
Эта инструкция вполне справляется со своей задачей, но вам, наверное, не встречались опытные программисты, записывающие код таким образом. Добавление значения к переменной происходит настолько часто, что в C# вам предоставляется способ выполнения этой задачи в более лаконичной записи с использованием оператора +=. Для добавления 42 к answer можно воспользоваться следующей инструкцией:
answer += 42;
В табл. 5.1 показано, что эта форма записи может использоваться для объединения с оператором присваивания любых арифметических операторов. Обобщенно такие операторы называются операторами составного присваивания.
Таблица 5.1
Вместо этой формы записи | Используйте эту форму записи |
переменная = переменная * число; | переменная *= число; |
переменная = переменная / число; | переменная /= число; |
переменная = переменная % число; | переменная %= число; |
переменная = переменная + число; | переменная += число; |
переменная = переменная - число; | переменная -= число; |
СОВЕТ Операторы составного присваивания пользуются таким же уровнем приоритета и имеют такую же ассоциативность, что и простой оператор присваивания (=).
Оператор += применяется также в отношении строк, он добавляет одну строку к концу другой строки. Например, при выполнении следующего кода на консоль выводится приветствие «Hello John»:
string name = "John";
string greeting = "Hello ";
greeting += name;
Console.WriteLine(greeting);
Никакие другие операторы составного присваивания со строками использоваться не могут.
СОВЕТ Вместо операторов составного присваивания, увеличивающих или уменьшающих значение переменной на единицу, следует использовать операторы инкремента (++) и декремента (--). Например, вместо
count += 1;
следует использовать
count++;
Инструкция while используется для повторных запусков инструкции до тех пор, пока заданное условие вычисляется в true. Для нее используется следующий синтаксис:
while ( булево выражение )
инструкция
Вычисляется булево выражение, которое нужно заключить в круглые скобки, и если его значение равно true, инструкция выполняется, а затем булево выражение вычисляется еще раз. Если выражение по-прежнему вычисляется в true, выполнение инструкции повторяется, а затем булево выражение вычисляется еще раз. Этот процесс продолжается, пока булево выражение не будет вычислено в false, и тогда происходит выход из инструкции while. Затем выполнение продолжается с первой инструкции, следующей за инструкцией while. Для инструкции while используется тот же синтаксис, что и для инструкции if (фактически синтаксис идентичен, за исключением ключевого слова):
• Выражение должно быть булевым.
• Булево выражение должно быть заключено в круглые скобки.
• Если булево выражение с первого же раза вычисляется в false, инструкция не выполняется.
• Если под управлением инструкции while нужно выполнить две и более инструкции, их следует сгруппировать в блок.
Посмотрите на инструкцию while, записывающую в консоль значения от 0 до 9. Обратите внимание на то, что как только переменная i достигнет значения 10, выполнение инструкции while завершается и код блока не выполняется:
int i = 0;
while (i < 10)
{
Console.WriteLine(i);
i++;
}
Когда-либо выполнение всех инструкций while должно завершаться. Новички довольно часто забывают включать инструкцию, вызывающую со временем вычисление булева выражения в false и прекращение цикла, из-за чего программа входит в режим бесконечного выполнения. В примере роль такой инструкции выполняет i++;.
ПРИМЕЧАНИЕ Переменная i в цикле while управляет количеством выполняемых в нем итераций. Это общая идиома, и переменную, играющую эту роль, иногда называют переменной-ограничителем. Можно также создавать вложенные циклы (один цикл внутри другого), и в этих случаях обычно эту схему имен расширяют, используя в качестве имен переменных-ограничителей, применяемых для управления итерациями в этих циклах, буквы j, k и даже l.
СОВЕТ Точно так же, как и при использовании инструкций if, с инструкцией while рекомендуется всегда использовать блок, даже если в нем содержится всего одна инструкция. Тогда, если позже будет принято решение о добавлении к телу конструктора while еще одной инструкции, будет совершенно ясно, что ее нужно добавлять к блоку. Если этого не сделать, то в качестве части цикла в конструкции while будет выполнена только та инструкция, которая следует непосредственно за булевым выражением, что приведет к возникновению трудно обнаруживаемых ошибок, похожих на те, которые возникают при использовании следующего кода:
int i = 0;
while (i < 10)
Console.WriteLine(i);
i++;
Этот код будет выполняться в цикле до бесконечности, выводя на консоль бесчисленное количество нулей, поскольку в качестве части конструкции while будет выполняться инструкция Console.WriteLine, но не будет выполняться инструкция i++;.
В следующем упражнении вам предстоит написать цикл while для построчного перебора содержимого текстового файла и записи каждой его строки в текстовое поле формы.
Откройте в Microsoft Visual Studio 2015 проект WhileStatement, который находится в папке \Microsoft Press\VCSBS\Chapter 5 \WhileStatement вашей папки документов.
Щелкните в меню Отладка на пункте Начать отладку. Среда Visual Studio 2015 выполнит сборку и запуск приложения, представляющего собой простой просмотрщик текстового файла, которым можно воспользоваться для выбора файла и вывода на экран его содержимого.
Щелкните на кнопке Open File (Открыть файл). Появится окно выбора файла, в котором, как показано на рис. 5.1, будут отображены файлы, находящиеся в папке документов (перечень файлов и папок может отличаться от того, который выводится на вашем компьютере).
Рис. 5.1
Этим диалоговым окном можно воспользоваться для перехода в папку и выбора файла для вывода на экран. Перейдите в папке документов в папку \Microsoft Press\VCSBS\Chapter 5\WhileStatement\WhileStatement. Выберите файл MainPage.xaml.cs и щелкните на кнопке Открыть.
В текстовом поле в верхней части формы появится имя файла, MainPage.xaml.cs, но содержимое этого файла в более крупном поле не появится. Дело в том, что вами еще не создан код, считывающий содержимое файла и отображающий его на экране. Эти функции будут добавлены на следующих этапах.
Вернитесь в Visual Studio 2015 и остановите отладку. Выведите код для файла MainPage.xaml.cs в окно редактора и найдите метод openFileClick.
Этот метод запускается, когда пользователь щелкает на кнопке Открыть в диалоговом окне открытия файла. Разбираться в подробностях работы этого метода вам пока не нужно, просто уясните тот факт, что этот метод выводит предложение пользователю выбрать файл (в панели выбора файла FileOpenPicker или в окне OpenFileDialog) и открывает выбранный файл для чтения.
Для нас важны две последние инструкции метода openFileClick, имеющие следующий вид:
TextReader reader = new StreamReader(inputStream.AsStreamForRead());
displayData(reader);
В первой инструкции объявляется TextReader-переменная по имени reader. TextReader — это класс, предоставляемый средой Microsoft.NET Framework, которым можно воспользоваться для чтения потоков символов из таких источников, как файлы. Он находится в пространстве имен System.IO. Эта инструкция открывает объекту TextReader, который затем может использоваться для чтения данных из файла, доступ к данным файла, указанного пользователем в панели FileOpenPicker. Последняя инструкция вызывает метод по имени displayData, передавая ему в качестве параметра переменную reader. Метод displayData, используя объект reader, считывает данные и выводит их на экран (или же он станет это делать, как только вы запишете код для выполнения этих действий).
Изучите метод displayData. Пока он выглядит следующим образом:
private void displayData(TextReader reader)
{
// TODO: add while loop here
}
Как видите, если не считать комментария, этот метод пуст. В него нужно добавить код для извлечения данных и вывода их на экран.
Замените комментарий // TODO: add while loop here следующей инструкцией:
source.Text = "";
Переменная source ссылается на большое текстовое поле формы. Установка для ее свойства Text значения пустой строки ("") удаляет любой текст, отображавшийся перед этим в данном текстовом поле.
Добавьте после предыдущей добавленной к методу displayData строки следующую инструкцию:
string line = reader.ReadLine();
Она объявляет строковую переменную по имени line и, чтобы считать в эту переменную первую строку из файла, вызывает метод reader.ReadLine. Этот метод возвращает либо следующую строку текста из файла, либо, когда больше нет строк для считывания, специальное значение, которое называется null.
Добавьте к методу displayData после только что введенного кода следующие инструкции:
while (line != null)
{
source.Text += line + '\n';
line = reader.ReadLine();
}
Это цикл while, производящий последовательный построчный перебор содержимого файла, пока строки не закончатся.
Булево выражение в начале цикла while проверяет значение переменной line. Если оно не равно null, тело цикла выводит текущую строку текста, добавляя ее, а вместе с ней и символ новой строки ('\n' — метод ReadLine объекта TextReader при считывании каждой новой строки удаляет символы новой строки, поэтому код нуждается в том, чтобы они были возвращены в конец строки), к свойству Text исходного текстового поля. Затем, прежде чем выполнить следующую итерацию, цикл while считывает новую строку текста. Выполнение цикла while завершается, когда в файле заканчивается текст для считывания, и метод ReadLine возвращает значение null.
Наберите после закрывающей фигурной скобки в конце цикла while следующую инструкцию:
reader.Dispose();
Эта инструкция закрывает файл и высвобождает связанные с ним ресурсы. Польза от ее применения в том, что теперь файлом смогут воспользоваться другие приложения, кроме того, будут высвобождены память и другие ресурсы, задействованные для доступа к файлу.
Щелкните в меню Отладка на пункте Начать отладку. Как только появится форма, щелкните на кнопке Open File. В панели выбора файла или в диалоговом окне его открытия перейдите к папке \Microsoft Press\VCSBS\Chapter 5\WhileStatement\WhileStatement в вашей папке документов, выберите файл MainPage.xaml.cs, а затем щелкните на кнопке Открыть.
ПРИМЕЧАНИЕ Не пытайтесь открыть файл, не содержащий текст. К примеру, при попытке открыть исполняемую программу или графический файл приложение просто покажет текстовое представление содержащейся в этом файле двоичной информации. Если размер файла довольно большой, он может «подвесить» приложение, что потребует от вас принудительного завершения его работы.
На этот раз содержимое выбранного файла появится в текстовом поле, и вы должны узнать отредактированный вами код. При запуске приложение должно вывести следующее изображение (рис. 5.2).
Рис. 5.2
Прокрутите текст в поле и найдите метод displayData. Убедитесь, что в нем содержится только что добавленный вами код.
Вернитесь в Visual Studio и остановите отладку.
В C# большинство записей инструкций while имеют следующую общепринятую структуру:
инициализация
while (булево выражение)
{
инструкция
обновляемая управляющая переменная
}
Инструкция for в C# предоставляет более формализованную версию конструкции данного типа, в которой объединены инициализация, булево выражение и код, обновляющий значение управляющей переменной. Несомненная польза от применения инструкции for заключается в том, что при этом практически невозможно случайно не указать код, инициализирующий или обновляющий управляющую переменную, поэтому вам вряд ли удастся написать код бесконечного цикла. Синтаксис инструкции for имеет следующий вид:
for (инициализация; булево выражение; обновляемая управляющая переменная)
инструкция
Инструкция, играющая роль тела конструкции for, может быть одной строкой кода или кодовым блоком, заключенным в фигурные скобки.
Показанный ранее цикл while, с помощью которого на экран выводились целые числа от 0 до 9, можно переделать в следующий цикл for:
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
Инициализация проводится только один раз, в самом начале цикла. Затем, если булево выражение вычисляется в true, запускается инструкция. Происходит обновление управляющей переменной, а затем булево выражение вычисляется еще раз. Если условие по-прежнему вычисляется в true, инструкция снова выполняется, управляющая переменная обновляется, булево выражение снова вычисляется и т.д.
Обратите внимание на то, что инициализация происходит только один раз, инструкция в теле цикла всегда выполняется перед обновлением переменной, а это обновление происходит перед новым вычислением булева выражения.
СОВЕТ Считается, что лучше, как и в инструкции while, всегда использовать кодовый блок, даже если в теле цикла for содержится всего одна инструкция. Тогда позже при добавлении к телу дополнительных инструкций вы обеспечите непременное выполнение своего кода в качестве части каждой из итераций.
Любая из трех частей инструкции for может быть опущена. Если опустить булево выражение, то условие всегда будет вычисляться в true и следующий цикл for станет выполняться бесконечно:
for (int i = 0; ;i++)
{
Console.WriteLine("somebody stop me!");
}
Если опустить те части, где осуществляются инициализация и обновление, получится что-то вроде необычной записи цикла while:
int i = 0;
for (; i < 10; )
{
Console.WriteLine(i);
i++;
}
ПРИМЕЧАНИЕ Части инструкции for, относящиеся к инициализации, булеву выражению и обновлению, всегда должны отделяться друг от друга точкой с запятой, даже если они опущены.
Циклу for можно также предоставить сразу несколько выражений инициализации и несколько выражений обновления. (Но булево выражение должно быть только одно.) Для этого различные инициализации и обновления нужно отделить друг от друга запятыми, как показано в следующем примере:
for (int i = 0, j = 10; i <= j; i++, j--)
{
...
}
В качестве заключительного примера посмотрим, как цикл while из предыдущего упражнения можно было бы переделать в цикл for:
for (string line = reader.ReadLine(); line != null; line = reader.ReadLine())
{
source.Text += line + '\n';
}
Возможно, вы уже заметили, что в инициализационной части инструкции for можно объявить переменную. Областью видимости этой переменной станет тело инструкции for, и она исчезнет, как только эта инструкция завершит выполнение. Это правило имеет два важных следствия. Во-первых, эту переменную невозможно использовать после завершения выполнения инструкции for, поскольку в области видимости ее больше нет. Посмотрите на следующий пример:
for (int i = 0; i < 10; i++)
{
...
}
Console.WriteLine(i); // ошибка в ходе компиляции
Во-вторых, можно записывать две и более инструкции for, заново использующие переменную с одним и тем же именем, поскольку, как показано в следующем примере кода, каждая переменная будет находиться в другой области видимости:
for (int i = 0; i < 10; i++)
{
...
}
for (int i = 0; i < 20; i += 2) // все в порядке
{
...
}
Инструкции while и for проводят проверку своих булевых выражений в самом начале цикла. Следовательно, если выражение при первой же проверке вычисляется в false, тело цикла ни разу не выполняется. Инструкция do действует по-другому: ее булево выражение вычисляется после каждой итерации, поэтому тело всегда выполняется как минимум один раз.
Синтаксис инструкции do выглядит следующим образом (не забудьте ставить завершающую точку с запятой):
do
инструкция
while (булево выражение);
Если в теле цикла содержится более одной инструкции, нужно использовать кодовый блок (если этого не сделать, компилятор выдаст синтаксическую ошибку). Вот как выглядит версия примера, записывающего на консоль значения от 0 до 9, которая теперь построена с применением инструкции do:
int i = 0;
do
{
Console.WriteLine(i);
i++;
}
while (i < 10);
Инструкции break и continue
В главе 4 было показано применение инструкции break для выхода из инструкции switch. Инструкцию break можно использовать также для выхода из тела инструкции итерации. При выходе из цикла его работа тут же прекращается, выполнение программы продолжается с первой инструкции, следующей за циклом. Но обновление и вычисление условия продолжения цикла больше не производятся. В отличие от этого, инструкция continue заставляет программу перейти к немедленному выполнению следующей итерации цикла (после перевычисления булева выражения). Посмотрите на еще одну версию примера, записывающего на консоль значения от 0 до 9, на этот раз с применением инструкций break и continue:
int i = 0;
while (true)
{
Console.WriteLine(i);
i++;
if (i < 10)
continue;
else
break;
}
Это абсолютно несуразный код. Многие руководства по программированию рекомендуют использовать инструкцию continue крайне осмотрительно или вообще отказаться от нее, поскольку зачастую это приводит к созданию кода, в котором очень трудно разобраться. Также порой инструкция continue обусловливает весьма странный ход выполнения программы. Например, если инструкция continue выполняется внутри инструкции for, то перед выполнением следующей итерации запускается та ее часть, которая обновляет значение управляющей переменной.
В следующем упражнении вы напишете инструкцию do, преобразующую положительное десятичное целое число в его строковое представление в восьмеричной форме записи. Программа основана на следующем алгоритме, в котором применяется широко известная математическая процедура:
сохраните десятичное число в переменной dec
сделайте следующее
разделите dec на 8 и сохраните остаток
установите для dec значение частного из предыдущего шага,
пока dec не равен нулю
объединяйте значения, сохраненные в остатке для каждого вычисления, в обратном
порядке
Предположим, к примеру, что вам нужно преобразовать десятичное число 999 в восьмеричное. Для этого нужно выполнить следующие шаги.
1. Разделить 999 на 8. Частное будет равно 124, а остаток — 7.
2. Разделить 124 на 8. Частное будет равно 15, а остаток — 4.
3. Разделить 15 на 8. Частное будет равно 1, а остаток — 7.
4. Разделить 1 на 8. Частное будет равно 0, а остаток — 1.
5. Объединить значения, вычисленные для остатка на каждом шаге, в обратном порядке. Получится результат 1747. Это и будет восьмеричным представлением десятичного значения 999.
Откройте в Visual Studio 2015 проект DoStatement, который находится в папке \Microsoft Press\VCSBS\Chapter 5\DoStatement вашей папки документов.
Выведите в окно конструктора форму MainPage.xaml. Эта форма содержит текстовое поле по имени number, в которое пользователь может ввести десятичное число.
Когда пользователь щелкает на кнопке Show Steps (Показать шаги), создается восьмеричное представление введенного числа. Результаты каждой стадии вычисления показываются в расположенном справа текстовом поле по имени steps.
Выведите в окно редактора кода и текста код файла MainPage.xaml.cs и найдите метод showStepsClick. Этот метод запускается, когда пользователь щелкает в форме на кнопке Show Steps. Пока что он пуст.
Добавьте в метод showStepsClick следующие инструкции, выделенные жирным шрифтом:
private void showStepsClick(object sender, RoutedEventArgs e)
{
int amount = int.Parse(number.Text);
steps.Text = "";
string current = "";
}
Первая инструкция превращает строковое значение в свойстве Text текстового поля number в целое число путем использования метода Parse, принадлежащего типу int, и сохраняет результат в локальной переменной по имени amount.
Вторая инструкция удаляет текст, отображаемый в текстовом поле steps, устанавливая в качестве значения его свойства Text пустую строку.
Третья инструкция объявляет строковую переменную по имени current и инициализирует ее значением пустой строки. Эта переменная будет применяться для хранения цифр, создаваемых при каждой итерации цикла, используемого для преобразования десятичного числа в его восьмеричное представление.
Добавьте к методу showStepsClick следующую инструкцию do (выделенную жирным шрифтом):
private void showStepsClick(object sender, RoutedEventArgs e)
{
int amount = int.Parse(number.Text);
steps.Text = "";
string current = "";
do
{
int nextDigit = amount % 8;
amount /= 8;
int digitCode = '0' + nextDigit;
char digit = Convert.ToChar(digitCode);
current = digit + current;
steps.Text += current + "\n";
}
while (amount != 0);
}
Используемый здесь алгоритм многократно выполняет целочисленную арифметическую операцию, деля значения переменной amount на 8 и определяя остаток. Этот остаток после каждого успешно выполненного деления представляет собой следующую цифру в создаваемой строке. Со временем, когда значение переменной amount сократится до нуля, цикл завершится. Заметьте, что код тела должен быть выполнен хотя бы один раз. Именно такое поведение нам и требуется, поскольку даже у числа 0 имеется одна восьмеричная цифра.
Если присмотреться к коду, можно заметить, что первой в цикле do выполняется следующая инструкция:
int nextDigit = amount % 8;
Она объявляет int-переменную по имени nextDigit и инициализирует ее остатком от деления значения переменной amount на 8. Этот остаток будет числом из диапазона от 0 до 7.
Следующей инструкцией в цикле do является
amount /= 8;
Это составное присваивание, эквивалентное записи amount = amount / 8;. Если значение amount равно 999, то после выполнения этой инструкции оно станет равно 124.
Следующей инструкцией является
int digitCode = '0' + nextDigit;
Тут необходимо кое-что пояснить. У символов имеется уникальный код, соответствующий набору символов, используемому операционной системой. В наборе символов операционной системы Windows у кода символа «0» имеется целочисленное значение 48. Код символа «1» имеет значение 49, символа «2» — 50 и так далее вплоть до кода символа «9», имеющего целочисленное значение 57. В C# можно рассматривать символ как целое число и выполнять над ним арифметические действия, но при этом C# использует в качестве значения код символа. Следовательно, выражение '0' + nextDigit фактически вычисляется в значение в диапазоне между 48 и 55 (вспомним, что значение nextDigit всегда будет между 0 и 7), что соответствует коду для эквивалентной восьмеричной цифры.
Четвертой инструкцией в цикле do является
char digit = Convert.ToChar(digitCode);
Эта инструкция объявляет символьную переменную по имени digit и инициализирует ее результатом вызова метода Convert.ToChar(digitCode). Метод Convert.ToChar получает целое число, содержащее код символа, и возвращает соответствующий символ. К примеру, если у digitCode значение 54, Convert.ToChar(digitCode) возвращает символ '6'.
В целом, первые четыре инструкции цикла do определяют символ, представляющий самую младшую (крайнюю справа) восьмеричную цифру, соответствующую числу, введенному пользователем. Следующей задачей будет добавление этой цифры к началу выводимой строки:
current = digit + current;
Следующей инструкцией в цикле do является
steps.Text += current + "\n";
Эта инструкция добавляет к текстовому полю steps строку, содержащую цифры, созданные до этого момента для восьмеричного представления числа. Кроме этого, инструкция добавляет символ новой строки, чтобы каждая стадия преобразования появлялась в текстовом поле на отдельной строке.
И наконец, в компоненте while в конце цикла do вычисляется условие:
while (amount != 0);
Поскольку значение переменной amount пока не равно нулю, цикл выполняет следующую итерацию.
В заключительном упражнении данной главы будет задействован отладчик Visual Studio 2015, позволяющий запустить пошаговое выполнение предыдущей инструкции do, чтобы помочь вам разобраться в том, как она работает.
В окне редактора, показывающего содержимое файла MainPage.xaml.cs, переместите курсор на первую инструкцию метода showStepsClick:
int amount = int.Parse(number.Text);
Щелкните правой кнопкой мыши на любом месте первой инструкции и выберите пункт Выполнить до текущей позиции (Run To Cursor). Когда появится форма, наберите в расположенном слева текстовом поле число 999 и щелкните на кнопке Show Steps (Показать шаги).
Программа остановится, и вы попадете в режим отладки Visual Studio 2015. Желтая стрелка в левом поле окна редактора и желтая фоновая подсветка выделят код текущей инструкции. Выведите панель инструментов отладки, если ее еще нет на экране (выберите в меню Вид пункт Панели инструментов и установите флажок Отладка).
ПРИМЕЧАНИЕ Команды панели отладки доступны также в меню Отладка, отображаемом на панели меню.
Щелкните в панели инструментов отладки на кнопке со стрелкой вниз, указывающей на пункт Добавить или удалить кнопки (Add Or Remove Buttons), а затем выберите пункт Окна (рис. 5.3).
Рис. 5.3
В результате этого к инструментам добавится кнопка Точки останова (Breakpoints Window).
Щелкните в панели отладчика на стрелке, которая находится сразу же за кнопкой Точки останова, а затем щелкните на пункте Локальные (Locals) (рис. 5.4).
Появится окно Локальные (если оно еще не было открыто). В нем отобразятся имена, значения и типы локальных переменных, имеющихся в текущем методе, включая локальную переменную amount. Обратите внимание на то, что текущим значением amount указан нуль (рис. 5.5).
Щелкните на панели отладчика на кнопке Шаг с заходом. Отладчик выполнит следующую инструкцию:
int amount = int.Parse(number.Text);
Рис. 5.4
Рис. 5.5
Значение переменной amount в окне Локальные изменится на 999, и желтая стрелка переместится на следующую инструкцию. Еще раз щелкните на кнопке Шаг с заходом. Отладчик выполнит следующую инструкцию:
steps.Text = "";
Это не повлияет на состояние содержимого окна Локальные, поскольку steps является элементом управления формы, а не локальной переменной. Желтая стрелка переместится на следующую инструкцию. Щелкните на кнопке Шаг с заходом. Отладчик выполнит следующую инструкцию:
string current = "";
Желтая стрелка переместится на фигурную скобку, открывающую цикл do. В этом цикле содержатся три собственные локальные переменные: nextDigit, digitCode и digit. Обратите внимание на их появление в окне Локальные и на то, что все три переменные изначально имеют нулевые значения.
Щелкните на кнопке Шаг с заходом. Желтая стрелка переместится на первую инструкцию внутри цикла do. Щелкните на кнопке Шаг с заходом. Отладчик выполнит следующую инструкцию:
int nextDigit = amount % 8;
Значение переменной nextDigit в окне Локальные изменится на 7. Это остаток от деления 999 на 8. Щелкните на кнопке Шаг с заходом. Отладчик выполнит такую инструкцию:
amount /= 8;
Значение переменной amount в окне Локальные изменится на 124. Щелкните на кнопке Шаг с заходом. Отладчик выполнит очередную инструкцию:
int digitCode = '0' + nextDigit;
Значение переменной digitCode в окне Локальные изменится на 55. Это код символа «7» (48 + 7). Щелкните на кнопке Шаг с заходом. Отладчик выполнит следующую инструкцию:
char digit = Convert.ToChar(digitCode);
Значение переменной digit в окне Локальные изменится на '7'. Символьные значения в окне Локальные отображаются как в исходном числовом значении (в данном случае 55), так и в символьном представлении ('7').
Обратите внимание на то, что значение переменной current в окне Локальные по-прежнему является пустой строкой "". Щелкните на кнопке Шаг с заходом. Отладчик выполнит следующую инструкцию:
current = current + digit;
Значение переменной current в окне Локальные изменится на "7". Щелкните на кнопке Шаг с заходом. Отладчик выполнит очередную инструкцию:
steps.Text += current + "\n";"
Эта инструкция выведет в текстовое поле steps текст "7", за которым следует символ новой строки, чтобы следующий вывод в текстовое поле отображался на новой строке. (Форма в данный момент скрыта за окном Visual Studio, поэтому вы ее увидеть не сможете.) Курсор переместится на закрывающую фигурную скобку в конце цикла do.
Щелкните на кнопке Шаг с заходом. Желтая стрелка переместится на инструкцию while для вычисления, позволяющего определить, завершился цикл do или же его следует продолжить для следующей итерации.
Щелкните на кнопке Шаг с заходом. Отладчик выполнит следующую инструкцию:
while (amount != 0);
Значение переменной amount равно 124, и выражение 124 != 0 вычисляется в true, следовательно, цикл do выполняет еще одну итерацию. Желтая стрелка переходит обратно к открывающей фигурной скобке в начале цикла do. Щелкните на кнопке Шаг с заходом. Желтая стрелка опять переместится на первую инструкцию внутри цикла do.
Продолжайте щелкать на кнопке Шаг с заходом, чтобы были пройдены следующие три итерации цикла do, и наблюдайте за тем, как в окне Локальные изменяются значения переменных.
В конце четвертой итерации цикла значение переменной amount станет равно нулю, а значение переменной current станет равно "1747". Желтая стрелка будет находиться на условии while в конце цикла do:
while (amount != 0);
Поскольку теперь значение переменной amount равно нулю, выражение amount != 0 будет вычислено в false и цикл do должен завершиться.
Щелкните на кнопке Шаг с заходом. Отладчик выполнит следующую инструкцию:
while (amount != 0);
Как и предсказывалось, цикл do завершается и желтая стрелка перемещается на закрывающую фигурную скобку в конце метода showStepsClick.
Щелкните в меню Отладка на пункте Продолжить. Появится форма, отображающая четыре этапа создания восьмеричного представления числа 999: 7, 47, 747 и 1747 (рис. 5.6).
Вернитесь в Visual Studio 2015. Щелкните в меню Отладка на пункте Остановить отладку.
Рис. 5.6
В данной главе вы узнали, как использовать операторы составного присваивания для обновления значения числовых переменных и для добавления одной строки к другой. Увидели, как использовать инструкции while, for и do для многократного выполнения кода до тех пор, пока некоторое булево выражение вычисляется в true.
Если вы хотите продолжить работу и изучить следующую главу, оставьте открытой среду Visual Studio 2015 и переходите к главе 6 «Обработка ошибок и исключений».
Если вы хотите выйти из среды Visual Studio 2015, то в меню Файл щелкните на пункте Выход. Если увидите диалоговое окно с предложением сохранить изменения, щелкните на кнопке Да и сохраните проект.
Чтобы | Сделайте следующее |
Добавить значение к переменной | Воспользуйтесь оператором составного присваивания со сложением, например: переменная += значение; |
Вычесть значение из переменной | Воспользуйтесь оператором составного присваивания с вычитанием, например: переменная -= значение; |
Выполнить одну или несколько инструкций нуль и более раз, пока условие вычисляется в true | Воспользуйтесь инструкцией while, например: int i = 0; while (i < 10) { Console.WriteLine(i); i++; } Или же воспользуйтесь инструкцией for, например: for (int i = 0; i < 10; i++) { Console.WriteLine(i); } |
Выполнить инструкции один или более раз | Воспользуйтесь инструкцией do, например: int i = 0; do { Console.WriteLine(i); i++; } while (i < 10); |