
Курс лекций CS (первый семестр)
.pdfКафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова
…
значениеN
}
Перечислимые типы могут использовать в качестве базовых следующие типы: byte, sbyte, short, ushort, int, uint, long и ulong.
По умолчанию каждому значению перечислимого типа автоматически присваивается соответствующее значение базового типа, начиная с нуля, в том порядке, в котором они описаны. Другими словами, значение1 получит базовое значение 0, значение2 — 1, значение3 — 2 и т.д. Для того чтобы переопределить такой порядок, следует использовать оператор = и фактические базовые значения для каждого перечислимого значения:
enum имяТипа : базовыйТип
{значение1=фактическоеЗначение1,
значение2=фактическоеЗначение2,
значение3=фактическоеЗначение3,
…
значениеN = фактическоеЗначениеN
}
Кроме того, существует возможность задавать идентичные базовые значения для нескольких перечислимых значений, используя одно значение как базовое значение другого:
enum имяТипа : базовыйТип
{
значение1= фактическоеЗначение1,
значение2 = значение1,
значение3;
…
значениеN = фактическоеЗначениеN
111
Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова
}
Всем значениям, оставшимся неуказанными, будут автоматически присвоены базовые значения; для этого используется последовательность, начинающаяся со значения, на единицу больше последнего явно заданного значения. В приведенном объявлении значение3 получит базовое значение, равное значение2+1. Это может привести к возникновению непредвиденных проблем, когда какие-либо из базовых значений, заданных после определения вроде значение2=значение1, окажутся идентичными другим базовым значениям. Так, например, в следующей программе базовое значение для значение4 и для значение2 будет одним и тем же:
enum имяТипа : базовыйТип
{
значение1= фактическоеЗначение1,
значение2 ,
значение3=значение1;
значение4
}
Это не является ошибкой.
112
Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова
Пример.
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{enum cvet
{
red=12,
green=10,
blue=9,
yellow=14,
white=15
}
class Program
{static void Main(string[] args)
{cvet my; while (true)
{Console.WriteLine("\nКакой цвет поля вывода:\n1-желтое\n2-синее\n3-
зеленое\n4-красное\n5-выход");
char otvet = Convert.ToChar(Console.ReadLine()); switch (otvet)
{case '1':
my = cvet.yellow; break;
case '2':
my = cvet.blue; break;
case '3':
my = cvet.green; break;
113
Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова
case '4':
my = cvet.red;
break;
default:
my = cvet.white;
break; |
} |
if (my != cvet.white)
{
Console.BackgroundColor = (ConsoleColor)my;//
ConsoleColor.Yellow;
Console.WriteLine("Привет");
Console.BackgroundColor = ConsoleColor.White;
}
else
{
Console.BackgroundColor = (ConsoleColor)my;
Console.WriteLine("Пока");
Console.ReadLine(); return;
}
Console.ReadLine(); |
} |
}} |
114

Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова
Результат.
115
Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова
Лекция №17.
Функции.
Все программы, с которыми мы работали до сих пор, имели форму единого блока, в ряде случаев включавшем циклы, позволяющие многократно выполнять отдельные строки кода, и ветвление, позволяющее выполнять некоторые операторы по условию. Если возникала необходимость выполнить какую-либо операцию над данными, то нужный код должен был находиться там, где он будет работать.
Однако оказывается, что такая структура кода весьма ограниченна. Довольно часто возникают ситуации, когда выполнение определенных задач — например, поиск максимального элемента массива — необходимо в различных местах программы. Конечно, можно размещать идентичные (или почти идентичные) участки кода в разных частях приложения каждый раз, когда в этом возникает необходимость, однако такой подход имеет свои недостатки. Изменение даже одной небольшой детали, касающейся выполнения общей задачи (например, исправление некоторой ошибки), потребует внесения изменений во многих местах, возможно, разбросанных по всему приложению, а размер таких приложений бывает очень большим. Пропуск одного места может привести к непоправимым последствиям и неверному использованию всего приложения.
Решением такого рода проблем является применение функций. Функции в С# - это средство, позволяющее выполнять некоторые участки кода в произвольном месте приложения. Функция по своей сути – это подпрограмма, которая может манипулировать данными и возвращать некоторое значение. Каждая программа С# имеет по крайней мере одну функцию Main(), которая при запуске программы вызывается автоматически. Функция Main() может вызывать другие функции, те, в свою очередь, могут вызывать следующие и т.д.
Каждая функция обладает собственным именем, и, когда оно встречается в программе, управление переходит к телу данной функции. Этот процесс называется вызовом функции (или обращением к функции). По возвращении из функции выполнение программы возобновляется со строки, следующей после вызова функции.
Синтаксис определения функции будет выглядеть следующим образом:
static <тип_возвращаемого_значения> <имя_функции> (<список входящих параметров>)
{
<тело_функции>
return <возвращаемое_значение>;
}
116
Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова
Тип возвращаемого значения функции и список ее формальных параметров называется сигнатурой функции. Тело функции представляет собой набор выражений, заключенных в фигурные скобки.
Ключевое слово static имеет отношение к понятиям объектно-ориентированного программирования, поэтому будет изучено нами позже. Замечание. Использовать слово static для всех своих функций.
Если функция имеет <возвращаемое_значение>, то необходимо использовать оператор return. Единственным ограничением в данном случае является требование, гласящее, что
<возвращаемое_значение> должно иметь <тип_возвращаемого_значения>.
<Тип_возвращаемого_значения> может быть любым, включая самые сложные типы.
Если функция ничего не возвращает, то <тип_возвращаемого_значения> должен быть void и тогда в теле функции не пишется оператор return, так как функция не имеет возвращаемого значения.
Для вызова функции необходимо в теле вызывающей функции в качестве оператора записать имя функции с круглыми скобками, даже в случае отсутствия списка входящих параметров.
Пример:
using System;
using System.Collections.Generic; using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Privet()
{
Console.WriteLine("Privet");
}
117

Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова
static void Main(string[] args)
{
Privet(); char otvet;
Console.WriteLine("Еще?\nд-да\nн-нет"); otvet = Convert.ToChar(Console.ReadLine()); while (otvet == 'д')
{
Privet(); Console.WriteLine("Еще?\nд-да\nн-нет"); otvet = Convert.ToChar(Console.ReadLine());
}
}
}
}
Результат:
В рассмотренном примере имеется два одинаковых фрагмента, имело бы смысл использовать еще одну функцию для ввода символа. Эта функция должна возвращать вводимый символ, поэтому она будет иметь <тип_возвращаемого_значения> - сhar и необходимо использовать оператор return.
Пример:
using System;
118
Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова
using System.Collections.Generic; using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Privet()
{
Console.WriteLine("Privet");
}
static char Vvod()
{
char ot; Console.WriteLine("Еще?\nд-да\nн-нет"); ot = Convert.ToChar(Console.ReadLine()); return ot;
}
static void Main(string[] args)
{
Privet();
char otvet = Vvod(); while (otvet == 'д')
{
Privet();
otvet = Vvod();
}
119
Кафедра теоретической механики ИМЭМ ОНУ им. И.И.Мечникова
}
}
}
Результат работы данной программы такой же. Замечание. В данном примере вызов функции Vvod() имеет другой вид, так как значение, которое она возвращает в функцию Main() необходимо принимать.
Примечание. В языке С# можно вызывать функцию, которая имеет
<возвращаемое_значение>, как функцию без <возвращаемого_значения>.
Например, в нашем примере можно вызвать функцию Vvod() следующим образом:
Vvod();
В рассмотренных примерах использовались функции без списка входящих параметров. Список входящих параметров называется также списком формальных параметров и представляет собой список всех параметров и их типов, разделенных запятыми.
Например.
static int myFunc(int a, double b)
{
операторы функции;
}
Список параметров описывает тип значения, которое будет передано функции при ее вызове. Фактические значения, передаваемые в функцию, называются аргументами.
int y = myFunc(3, 5.6);
Здесь целая переменная y инициализируется значением, возвращаемым функцией myFunc, в качестве аргументов этой функции передаются значения 3 и 5.6. Тип аргументов должен соответствовать объявленным типам параметров.
120