Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Другие элементы меню 4 страница




Операторы break и continue

В структурном программировании признаются полезными «переходы вперед» (но не назад), позволяющие при выполнении некоторого условия выйти из цикла, оператора выбора, из блока. Для этой цели можно использовать оператор goto, но лучше использовать специально предназначенные для этих целей операторы break и continue.

Оператор break может стоять в теле цикла или завершать case-ветвь в операторе switch. Пример его использования в операторе switch уже демонстрировался. При выполнении оператора break в теле цикла завершается выполнение самого внутреннего цикла. В теле цикла, чаще всего, оператор break помещается в одну из ветвей оператора if, проверяющего условие преждевременного завершения цикла:

public void Jumps()

{

int i = 1, j=1;

for (i =1; i<100; i++)

{

for (j = 1; j<10;j++)

{

if (j>=3) break;

}

Console.WriteLine("Выход из цикла j при j = {0}", j);

if (i>=3) break;

}

Console.WriteLine("Выход из цикла i при i= {0}", i);

}// Jumps

Оператор continue используется только в теле цикла. В отличие от оператора break, завершающего внутренний цикл, continue осуществляет переход к следующей итерации этого цикла.

Оператор return

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

return [выражение];

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

Операторы цикла

Без циклов жить нельзя в программах, нет.

Оператор for

Наследованный от С++ весьма удобный оператор цикла for обобщает известную конструкцию цикла типа арифметической прогрессии. Его синтаксис:

for (инициализаторы; условие; список_выражений) оператор

Оператор, стоящий после закрывающей скобки, задает тело цикла. В большинстве случаев телом цикла является блок. Сколько раз будет выполняться тело цикла, зависит от трех управляющих элементов, заданных в скобках. Инициализаторы задают начальное значение одной или нескольких переменных, часто называемых счетчиками или просто переменными цикла. В большинстве случаев цикл for имеет один счетчик, но часто полезно иметь несколько счетчиков, что и будет продемонстрировано в следующем примере. Условие задает условие окончания цикла, соответствующее выражение при вычислении должно получать значение true или false. Список выражений, записанный через запятую, показывает, как меняются счетчики цикла на каждом шаге выполнения. Если условие цикла истинно, то выполняется тело цикла, затем изменяются значения счетчиков и снова проверяется условие. Как только условие становится ложным, цикл завершает свою работу. В цикле for тело цикла может ни разу не выполняться, если условие цикла ложно после инициализации, а может происходить зацикливание, если условие всегда остается истинным. В нормальной ситуации тело цикла выполняется конечное число раз.

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

В качестве примера рассмотрим классическую задачу: является ли строка текста палиндромом. Напомню, палиндромом называется симметричная строка текста, читающаяся одинаково слева направо и справа налево. Для ее решения цикл for подходит наилучшим образом: здесь используются два счетчика – один возрастающий, другой убывающий. Вот текст соответствующей процедуры:

/// <summary>

/// Определение палиндромов.

/// Демонстрация цикла for

/// </summary>

/// <param name="str"> текст </param>

/// <returns> true - если текст является палиндромом </returns>

public bool Palindrom(string str)

{

for (int i =0,j =str.Length-1; i<j; i++,j--)

if (str[i]!=str[j]) return (false);

return (true);

}// Palindrom

Циклы While

Цикл while(выражение) является универсальным видом цикла, включаемым во все языки программирования. Тело цикла выполняется до тех пор, пока остается истинным выражение while. В языке C# у этого вида цикла две модификации – с проверкой условия в начале цикла и в конце цикла. Первая модификация имеет следующий синтаксис:

while(выражение) оператор

Эта модификация цикла соответствует стратегии: «вначале проверь, а потом делай». В результате проверки может оказаться, что и делать ничего не нужно. Тело такого цикла может ни разу не выполняться. Конечно же, возможно и зацикливание. В нормальной ситуации каждое выполнение тела цикла – это очередной шаг к завершению цикла.

Цикл, проверяющий условие завершения в конце, соответствует стратегии: «вначале делай, а потом проверь». Тело такого цикла выполняется по меньшей мере один раз. Вот синтаксис этой модификации:

оператор

while (выражение);

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

/// <summary>

/// Два цикла: с проверкой в конце и в начале.

/// Внешний цикл - образец многократно решаемой задачи.

/// Завершение цикла определяется в диалоге с пользователем.

/// </summary>

public void Loop()

{

string answer, text;

{

Console.WriteLine("Введите слово");

text = Console.ReadLine();

int i =0, j = text.Length-1;

while ((i<j) && (text[i] == text[j]))

{i++; j--;}

if (text[i] == text[j])

Console.WriteLine(text +" - это палиндром!");

Console.WriteLine(text +" - это не палиндром!");

Console.WriteLine("Продолжим? (yes/no)");

answer = Console.ReadLine();

}

while (answer =="yes");

}// Loop

Цикл foreach

Новым видом цикла, не унаследованным от С++, является цикл foreach, удобный при работе с массивами, коллекциями и другими подобными контейнерами данных. Его синтаксис:

foreach (тип идентификатор in контейнер) оператор

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

Серьезным недостатком циклов foreach в языке C# является то, что цикл работает только на чтение, но не на запись элементов. Так что наполнять контейнер элементами приходится с помощью других операторов цикла.

В приведенном ниже примере показана работа с трехмерным массивом. Массив создается с использованием циклов типа for, а при нахождении суммы его элементов, минимального и максимального значения используется цикл foreach:

/// <summary>

/// Демонстрация цикла foreach.

/// Вычисление суммы, максимального и минимального

/// элементов трехмерного массива,

/// заполненного случайными числами.

/// </summary>

public void SumMinMax()

{

int [,,] arr3d = new int [10,10,10];

Random rnd = new Random();

for (int i =0; i<10; i++)

for (int j =0; j<10; j++)

for (int k =0; k<10; k++)

arr3d[i,j,k]= rnd.Next(100);

 

long sum =0; int min=arr3d[0,0,0], max=arr3d[0,0,0];

foreach (int item in arr3d)

{

sum +=item;

if (item > max) max = item;

else if (item < min) min = item;

}

Console.WriteLine("sum = {0}, min = {1}, max = {2}",

sum, min, max);

}// SumMinMax

Вариант 1

19. Чему будет равно x в результате выполнения следующего фрагмента:
int x=5; for(int i =1; i<5; i++); x+=5;

q 5;

q 10;

q 25;

q 30;

q 20.

20. Отметьте истинные высказывания:

q присваивание является операцией языка C#;

q добавление пустого оператора в последовательность операторов не меняет смысла программы;

q в теле оператора foreach текущий элемент позволяет получать и изменять значения элементов, хранящихся в контейнере;

q в операторе if число ключевых слов if должно совпадать с числом слов else;

q Case-выражение в операторе switch может задавать диапазон значений.

21. В каких фрагментах возникнет ошибка:

q int x=5, y =2*2+1, z; if(y=x) z=2*x; else z=x+y;

q int a=2, b=3,c=5, x; if(a<b)if(c>a)if(c>a+b) x=a+b+c;;

q int x, y, z; if (5 >4) x=5; y=x; z=y;

q int x=5, y, z; if(x>4) y=x; z=y;

Вариант 2

22. Чему будет равно x в результате выполнения следующего фрагмента:
int a=2, b=3,c=5, x=0; if(a>b)if(c>a)if(c>a+b) x=a+b+c; else x=7;else x=12;

q 0;

q 7;

q 10;

q 12.

23. Отметьте истинные высказывания:

q любое выражение может использоваться в качестве оператора;

q оператор if может быть эквивалентен по своему действию пустому оператору;

q оператор foreach не применим при работе с массивами;

q каждая case-ветвь оператора switch должна заканчиваться оператором break.

24. В каких фрагментах возникнет ошибка:

q int x=5, y =2*2+1, z; if(y >=x) z=2*x; else z=x+y;

q int x=5; {int y = 7; } int z = x+y;

q string s, s1, s2,s3; s=s1 =s2 =s3 ="око";

q switch(s)

q {

q case s1: x=3; break;

q case s2:

q case s3: x=5; break;

q }

q for (int Sum =0, i=0; i<N; i++) Sum += Arr[i]; (N и Arr определены должным образом).

Вариант 3

22. Тело цикла for (int i = 1, j=-10; i< 10; i--) j++;

q ни разу не выполнится;

q выполнится 3 раза;

q произойдет зацикливание;

q выполнится конечное число раз, большее 3-х.

23. Отметьте истинные высказывания:

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

q оператор switch по своему действию может быть эквивалентен пустому оператору;

q счетчик цикла оператора for по завершении цикла не определен;

q в теле оператора foreach не допускается присваивание значения текущему элементу.

24. В каких фрагментах возникнет ошибка:

q x=;; y=7;

q int x=5, z; {int y=7; z=y+1;} int w = x+z;

q string s="кок";

q switch(s)

q {

q case "око": break;

q case "кок":

q case "рок": s="тук"; s=s+s; break;

q }

q int x=5, y, z; if(x>4) y=x; else y=4; z=y;

 

 

Лекция 9. Процедуры и функции – методы класса

Процедуры и функции – две формы функционального модуля. Чем отличаются эти формы? Процедуры и функции – это методы класса. Описание методов (процедур и функций). Синтаксис. Атрибуты доступа. Статические и динамические методы. Формальные аргументы. Статус аргументов. Тело методов. Вызов процедур и функций. Фактические аргументы. Семантика вызова. Поля класса или аргументы метода? Поля класса или функции без аргументов. Проектирование класса Account. Функции с побочным эффектом. Перегрузка методов.

Ключевые слова: процедуры; функции; класс; библиотеки классов; отсутствие результата; входные и выходные аргументы; описание заголовка; описание тела; сигнатура метода; метод открыт; метод закрыт; произвольное число фактических аргументов; params; входные, выходные и обновляемые параметры; блок; return(выражение); вызов метода; соответствие списков формальных и фактических аргументов; ref; out вызов по ссылке; вызов по значению; поля класса или функции без аргументов; функция с побочным эффектом; перегрузка.

Процедуры и функции – функциональные модули

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

Процедуры и функции – методы класса

Долгое время процедуры и функции играли не только функциональную, но и архитектурную роль. Весьма популярным при построении программных систем был метод функциональной декомпозиции «сверху вниз», и сегодня еще играющий важную роль. Но с появлением ООП архитектурная роль функциональных модулей отошла на второй план. Для ОО-языков, к которым относится и язык C#, роль архитектурного модуля играет класс. Программная система строится из модулей, роль которых играют классы, но каждый из этих модулей имеют содержательную начинку, задавая некоторую абстракцию данных.

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

В данном контексте понятие класс распространяется и на все его частные случаи – структуры, интерфейсы, делегаты.

В языке C# нет специальных ключевых слов – procedure и function, но присутствуют сами понятия. Синтаксис объявления метода позволяет однозначно определить, чем является метод – процедурой или функцией.

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

Уже в лекции 1 мы говорили о роли библиотеки FCL – статическом компоненте Framework.Net. В лекции 4 рассматривались возможности класса Convert этой библиотеки, а в лекции 7 рассматривались классы Math и Random. Изучение классов FCL будет постоянно сопровождать наш курс.

Процедуры и функции. Отличия

Функция отличается от процедуры двумя особенностями:

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

вызывается в выражениях.

Процедура C# имеет свои особенности:

возвращает формальный результат void, указывающий на отсутствие результата;

вызов процедуры является оператором языка;

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

Хорошо известно, что одновременное существование в языке процедур и функций в каком-то смысле избыточно. Добавив еще один выходной аргумент любую функцию можно записать в виде процедуры. Справедливо и обратное. Если допускать функции с побочным эффектом, то любую процедуру можно записать в виде функции. В языке С – дедушке C# – так и сделали, оставив только функции. Однако значительно удобнее иметь обе формы реализации метода – процедуры и функции. Обычно метод предпочитают реализовать в виде функции тогда, когда он имеет один выходной аргумент, рассматриваемый как результат вычисления значения функции. Возможность вызова функций в выражениях также влияет на выбор в пользу реализации метода в виде функции. В других случаях метод реализуют в виде процедуры.

Описание методов (процедур и функций). Синтаксис

Синтаксически в описании метода различают две части – описание заголовка и описание тела метода:

заголовок_метода

тело_метода

Рассмотрим синтаксис заголовка метода:

[атрибуты][модификаторы]{void| тип_результата_функции} имя_метода([список_формальных_аргументов])

Имя метода и список формальных аргументов составляют сигнатуру метода. Заметьте, в сигнатуру не входят имена формальных аргументов, здесь важны типы аргументов. В сигнатуру не входит и тип возвращаемого результата.

Квадратные скобки (метасимволы синтаксической формулы) показывают, что атрибуты и модификаторы могут быть опущены при описании метода. Подробное их рассмотрение будет дано в лекциях, посвященных описанию классов. Сейчас же упомяну только об одном из модификаторов – модификаторе доступа. У него четыре возможных значения, из которых пока рассмотрим только два – public и private. Модификатор public показывает, что метод открыт и доступен для вызова клиентами и потомками класса. Модификатор private говорит, что метод предназначен для внутреннего использования в классе и доступен для вызова только в теле методов самого класса. Заметьте, если модификатор доступа опущен, то по умолчанию предполагается, что он имеет значение private и метод является закрытым для клиентов и потомков класса.

Обязательным при описании заголовка является указание типа результата, имени метода и круглых скобок, наличие которых необходимо и в том случае, если сам список формальных аргументов отсутствует. Формально тип результата метода указывается всегда, но значение void однозначно определяет, что метод реализуется процедурой. Тип результата, отличный от void, указывает на функцию. Вот несколько простейших примеров описания методов:

void A() {…};

int B(){…);

public void C(){…};

Методы A и B являются закрытыми, а метод С – открыт. Методы A и С реализованы процедурами, а метод B – функцией, возвращающей целое значение.

Список формальных аргументов

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

Рассмотрим теперь синтаксис объявления формального аргумента:

[ref|out|params]тип_аргумента имя_аргумента

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

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

Содержательно, все аргументы метода разделяются на три группы: входные, выходные и обновляемые. Аргументы первой группы передают информацию методу, их значения в теле метода только читаются. Аргументы второй группы представляют собой результаты метода, они получают значения в ходе работы метода. Аргументы третьей группы выполняют обе функции. Их значения используются в ходе вычислений и обновляются в результате работы метода. Выходные аргументы всегда должны сопровождаться ключевым словом out, обновляемые – ref. Что же касается входных аргументов, то, как правило, они задаются без ключевого слова, хотя иногда их полезно объявлять с параметром ref, о чем подробнее скажу чуть позже. Заметьте, если аргумент объявлен как выходной с ключевым словом out, то в теле метода обязательно должен присутствовать оператор присваивания, задающий значение этому аргументу. В противном случае возникает ошибка еще на этапе компиляции.

Для иллюстрации давайте рассмотрим группу методов класса Testing из проекта ProcAndFun, сопровождающего эту лекцию:

/// <summary>

/// Группа перегруженных методов A()

/// первый аргумент представляет сумму кубов

/// произвольного числа оставшихся аргументов

/// Аргументы могут быть разного типа.

/// </summary>

void A(out long p2, int p1)

{

p2 =(long) Math.Pow(p1,3);

Console.WriteLine("Метод A-1");

}

void A(out long p2, params int [] p)

{

p2=0; for (int i=0; i <p.Length; i++)

p2 += (long)Math.Pow(p[i],3);

Console.WriteLine("Метод A-2");

}

void A(out double p2, double p1)

{

p2 = Math.Pow(p1,3);

Console.WriteLine("Метод A-3");

}

void A(out double p2, params double [] p)

{

p2=0; for (int i=0; i <p.Length; i++)

p2 += Math.Pow(p[i],3);

Console.WriteLine("Метод A-4");

}

/// <summary>

/// Функция с побочным эффектом

/// </summary>

/// <param name="a"> Увеличивается на 1 </param>

/// <returns> значение a на входе </returns>

int f(ref int a)

{

return (a++);

}

Четыре перегруженных метода с именем A и метод f будут использоваться при объяснении перегрузки и побочного эффекта. Сейчас проанализируем только их заголовки. Все методы закрыты, поскольку объявлены без модификатора доступа. Перегруженные методы с именем A являются процедурами, метод f – процедурой. Все четыре перегруженных метода имеют разную сигнатуру. Хотя имена и число аргументов у всех методов одинаковы, но типы и ключевые слова, предшествующие аргументам, различны. Первый аргумент у всех четырех перегруженных методов является выходным и сопровождается ключевым словом out, в теле метода этому аргументу присваивается значение. Аргумент функции f является обновляемым, он снабжен ключевым словом ref, в теле функции используется его значение для получения результата функции, но и само значение аргумента изменяется в теле функции. Два метода из группы перегруженных методов используют ключевое слово params для своего последнего аргумента. Позже мы увидим, что при вызове этих методов этому аргументу будет соответствовать несколько фактических аргументов, число которых может быть произвольным.

Тело метода

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

Оператор return описан в лекции 8.

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

Область видимости, время жизни переменных, конфликты имен рассмотрены в лекции 5, семантика операторов – в лекции 8. Дополнительные сведения о семантике выполнения метода будут даны в этой лекции.

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

Вызов метода. Синтаксис

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

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

Сам вызов метода, независимо от того, процедура это или функция, имеет один и тот же синтаксис:

имя_метода([список_фактических_аргументов])

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

[ref|out]выражение

О соответствии списков формальных и фактических аргументов

Между списком формальных и списком фактических аргументов должно выполняться определенное соответствие по числу, порядку следования, типу и статусу аргументов. Если в первом списке n формальных аргументов, то фактических аргументов должно быть не меньше n (соответствие по числу). Каждому i-му формальному аргументу (для всех i от 1 до n-1) ставится в соответствие i-й фактический аргумент. Последнему формальному аргументу при условии, что он объявлен с ключевым словом params, ставятся в соответствие все оставшиеся фактические аргументы (соответствие по порядку). Если формальный аргумент объявлен с ключевым словом ref или out, то фактический аргумент должен сопровождаться таким же ключевым словом в точке вызова (соответствие по статусу).

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

Если формальный аргумент объявлен с типом T, то выражение, задающее фактический аргумент должно быть согласовано по типу с типом T – допускает преобразование к типу T, совпадает c типом T или является его потомком (соответствие по типу).

Если формальный аргумент является выходным – объявлен с ключевым словом ref или out, то соответствующий фактический аргумент не может быть выражением, поскольку используется в левой части оператора присваивания, так что он должен быть именем, которому можно присвоить значение.

Вызов метода. Семантика

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

Для простоты понимания семантики вызова можно полагать, что в точке вызова создается блок, соответствующий телу метода (реально все происходит значительно эффективнее). В этом блоке происходит замена имен формальных аргументов фактическими аргументами. Для выходных аргументов, для которых фактические аргументы также являются именами, эта замена или передача аргументов происходит по ссылке, означая замену формального аргумента ссылкой на реально существующий объект, заданный фактическим аргументом. Чуть более сложную семантику имеет вызов по значению, применяемый к формальным аргументам, объявленным без ключевых слов ref и out. При вычислении выражений, заданных такими фактическими аргументами, их значения присваиваются специально создаваемым переменным, локализованным в теле исполняемого блока. Имена этих локализованных переменных и подставляются вместо имен формальных аргументов. Понятно, что тип локализованных переменных определяется типом соответствующего формального аргумента. Понятно также, что семантика замены формальных аргументов фактическими – это по сути семантика оператора присваивания.




Поделиться с друзьями:


Дата добавления: 2014-12-25; Просмотров: 613; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.127 сек.