Конспект третьей лекции Метод Main может иметь четыре формата a. int Main() – без параметров и возвращает значение типа int b. int Main(string[] args) – с параметром – массивом строк, смысл которого рассматривается ниже c. void Main() – без параметров и не возвращает значения d. void Main(string[] args) – то же, но с параметром-массивом строк Смысл возвращаемого значения типа int метода Main. Операционная система, запуская программу на C#, фактически вызывает только один метод – метод Main. Результат выполнения этого метода, если это целое число, записывается в переменную среды с именем ERRORLEVEL (см. http://ru.wikipedia.org/wiki/COMMAND.COM). Проверив это значение, можно принять решение о действиях, наступающих после окончания работы процесса. Для иллюстрации создаем 3 проекта типа ConsoleApplication. Первый назовем host, а последующие два pr0 и pr1. В проекте host меняем тип, возвращаемый Main, на int и внутри Main пишем код static int Main(string[] args) { return 0; // Оператор return обязателен, если метод возвращает значение } В этом примере Main возвратит значение 0. В проектах pr0 и pr1 в методах Main пишем соответствующие строки кода: Console.WriteLine("Это проект pr0"); Console.ReadLine(); и Console.WriteLine("Это проект pr1"); Console.ReadLine(); Компилируем каждый из 3-ех проектов. В блокноте набираем текст так называемого пакетного файла @echo off host @if "%ERRORLEVEL%" == "0" pr0 @if "%ERRORLEVEL%" == "1" pr1 Сохраняем этот текст в какой-либо каталог с именем host. Меняем расширение host.txt на host.bat. В тот же каталог копируем exe-файлы скомпилированных проектов host.exe, pr0.exe и pr1.exe. Эти исполняемые файлы создаются при компиляции средой и помещаются в каталоги bin/Debug (или, возможно, bin/Release) внутри каталогов соответствующими именами host, pr0, pr1 проектов. Они, собственно, и содержат скомпилированный код проектов. После этого щелкаем по файлу host.bat. Он должен активировать файл host.exe, а затем, в зависимости от того, что возвращает метод Main процесса host, активировать либо процесс pr0 (если host возвратил 0), либо pr1 (если host возвратил 1). В нашей редакции host возвратил 0 и на экране должна появиться строка процесса pr0 " Это проект pr0". Замените return 0 на return 1 в методе Main проекта host, скомпилируйте его и скопируйте host.exe в каталог с bat-файлом, заменив прежнюю версию host.exe новой. Вновь запустите host.bat. Теперь должен выполняться процесс pr1 и сообщение на экране будет " Это проект pr1". Смысл параметра string[] args метода Main. Тип параметра – массив строк. Имя args является условным. Массив args содержит так называемые аргументы командной строки. Число аргументов-строк в этом массиве может быть любым. Они перечисляются при активации приложения через пробел после имени приложения. Например, если активировать процесс host.exe с одной строкой "dhjki90dj", командная строка активации из каталога, в котором находится host.exe, будет иметь вид host.exe dhjki90dj. Тогда массив args будет содержать одну строку dhjki90dj. Это легко проверить. С этой целью добавьте в метод Main приложения host (перед оператором return) строки кода Console.WriteLine(args[0]); Console.ReadLine(); Скомпилируйте проект. Найдите в главном меню кнопки Пуск операционной системы команду "Выполнить" (или "Run"). Используя кнопку обзора, найдите только что скомпилированный файл host.exe (в папке host/bin/Debug). В полученной маршрутной строке команды добавьте через пробел какой-либо набор символов. Активируйте команду "Выполнить". Убедитесь, что результатом будет набранная вами строка. Можно задавать аргументы командной строки непосредственно в среде. Для этого В меню Project выберите последнюю команду host Properties… В открывшемся окне слева выберите вкладку Debug На правой панели найдите окно с заголовком Command Line Arguments: В этом окне задайте строку. Именно она и будет первым аргументом. Скомпилируйте проект и запустите его непосредственно в среде. Оператор switch и операторы цикла Далее – содержимое метода Main проекта host, которое составлялось на лекции. Не забывайте изменять аргументы командной строки в свойствах проекта host для выбора различных случаев! // Циклы switch (args[0]) { case "1": // Цикл с перечислением: // 1. Оператор, инициализирующий счетчик цикла // 2. Логическое выражение возвращает условие окончания цикла // Если условие true, то выполняется оператор внутри цикла; // Если нет, управление передается оператору, следующему за циклом // 3. После выполнения оператора внутри цикла - счетчик меняет значение // 4. Вновь проверяется условие for (int i = 0; i < 30; i++) Console.WriteLine(i); Console.ReadLine(); break; //2 case "2": { // любое из выражений - инициализация, условие, изменение // могут отсутствовать int i = 0; for (; i < 30; i++) Console.WriteLine(i); Console.ReadLine(); break; } //3 case "3": { // бесконечный цикл int i = 0; for (; ; i++) Console.WriteLine(i); } //4 case "4": { // Оператор continue обходит операторы, следующие за ним внутри цикла // Оператор % определяет остаток от деления нацело // Метод Sleep класса System.Threading.Thread останавливает процесс // на заданное кол-во миллисекунд. int i = 0; for (; ; i++) { if (i % 2 == 0) continue; Console.WriteLine(i); System.Threading.Thread.Sleep(100); } } //5 case "5": { // Другой способ записать условие четности int i = 0; for (; ; i++) { // Здесь оператор & означает побитовое умножение целых чисел // Так как у числа 1 только в младшем бите единица, то в результате операции i & 1 будет // значение младшего бита числа i. Если там 0, то число i – четное. // Если написать условие в виде i & 1 == 0 будет ошибка. В чем тут дело? if ((i & 1) == 0) continue; Console.WriteLine(i); System.Threading.Thread.Sleep(100); } } //6 case "6": { // Подсчет числа шагов цикла за ед. времени // Структура DateTime // Обратите внимание на операцию вычитания значений структур типа DateTime. // Оператор break прерывает цикл и // передает управление оператору, следующему за циклом int i = 0, delay = 10; DateTime startTime = DateTime.Now; for (; ; i++) if ((DateTime.Now - startTime).Seconds > delay) break; // Строка форматирования n указывает, что должны быть пробелы между // разрядами, кратными тысяче. Console.WriteLine("step per sec = {0:n}", 1.0 * i / delay); Console.ReadLine(); break; } //7 case "7": { // Вычисление факториала // Цикл с предусловием Console.Write("n="); int n = int.Parse(Console.ReadLine()), f = 1; while (n > 1) f *= n--; // Это тоже, что написать два оператора // f=f*n; n=n-1; Console.WriteLine("f={0}", f); Console.ReadLine(); break; } //8 case "8": // Цикл с постусловием // Метод ReadKey, // Тип enum ConsoleKey do { // Вычисление факториала Console.Write("n="); int n = int.Parse(Console.ReadLine()), f = 1; while (n > 1) f *= n--; Console.WriteLine("f={0}\n{1}", f, "Press any key to continue or esc to exit"); } while (Console.ReadKey(true).Key != ConsoleKey.Escape); break; //9 case "9": // Минимальное отличие от нуля Console.WriteLine("Epsilon={0}", Double.Epsilon); Console.WriteLine(Double.Epsilon * .5 == 0); // Минимальное отличие от единицы Double pDelta = 1, mDelta = 1; do pDelta *= .5; while (1 + pDelta * .5 != 1); Console.WriteLine("pDelta={0}", pDelta); do mDelta *= .5; while (1 - mDelta * .5 != 1); Console.WriteLine("mDelta={0}", mDelta); Console.WriteLine(Double.IsPositiveInfinity((1 + pDelta) * Double.MaxValue)); Console.ReadLine(); break; } return 1; Успехов! Если есть вопросы – почта [email protected]. Фомин Георгий Викторович.