Использование параметров и возвращаемых значений

Функции

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

Определение функции состоит из следующих элементов:

  • Два ключевых слова: static и типа возвращаемого значения (void, если ничего не возвращает).
  • Имя функции, за которым следуют круглые скобки, внутри которых размещаются параметры.
  • Заключенный в фигурные скобки блок кода, который подлежит выполнению.

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

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

При использовании параметра-значения в функцию передается копия значения переменной из вызывающей функции и ее изменение в функции не изменяет значение переменной в вызывающей функции.

При использовании параметров-ссылок и выходных параметров в функцию передается адрес переменной из вызывающей функции, что дает ей возможность доступа к самой переменной. Параметры-ссылки и выходные параметры используют модификаторы ref и out перед параметром как в определении, так и в вызове функции.

Существуют два важных отличия:

  • В качестве параметра ref применять неинициализированную переменную нельзя, а в качестве out – можно.
  • Параметр out должен трактоваться функцией, которая его использует, как не имеющий присвоенного значения.

Преимущества использования функций по сравнению с многократным использованием повторяющегося кода:

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

Предлагаемое рассмотрение функций охватывает следующие ключевые моменты:

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

Любой проект консольного или оконного типа должен иметь по крайней мере одну точку входа, определяемую статической функцией Main(). Каждая функция, в том числе и функция Main(), должна принадлежать какому-нибудь классу, т.е. быть методом. Функция Main() объявляется как статический метод, не требующий создания экземпляра (Instance) класса для ее вызова. (Внимание! В приложении, имеющем несколько классов, функция Main() может входить в несколько из них. В этом случае для определения единственной точки входа нужно определить через окно свойств проекта, какой именно класс будет стартовым для данного приложения.)

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

Глобальные переменные

Скомпилируйте и выполните (по очереди) все фрагменты программ Пример 1 и Пример 2 (включая закомментированные) и объясните результаты.

Пример 1.

//Область видимости переменных в функциях

using System;

namespace Func01

{

class Program

{

/* static void Write()

{

Console.WriteLine("myString = {0}",myString);//ошибка

}

static void Main(string[] args)

{

string myString = "String defined in Main()");//не используется

Write();

Console.ReadKey();

}

*/

//описать последовательность выполнения операторов

/* static void Write()

{

string myString = "строка из Write()";//локальная

Console.WriteLine("\n это Write()!");

Console.WriteLine("myString = {0}", myString);

}

static void Main(string[] args)

{

string myString = "строка из Main()";//локальная переменная

Write();

Console.WriteLine("\n это Main()");

Console.WriteLine("myString = {0}", myString);

Console.ReadKey();

}

*/

static string myString;//глобальная переменная

static void Write()

{

string myString = "строка из Write()";//локальная переменная

Console.WriteLine("\n это Write()");

Console.WriteLine("Local myString = {0}", myString);

Console.WriteLine("Global myString = {0}", Program.myString);

}

static void Main(string[] args)

{

string myString = "строка из Main()";//локальная переменная

Program.myString = "Global string";

Write();

Console.WriteLine("\n это Main()");

Console.WriteLine("Local myString = {0}", myString);

Console.WriteLine("Global myString = {0}", Program.myString);

Console.ReadKey();

}

}

}

//------------------------------------------------------------------------

Пример 2

//область видимости переменных в других структурах

using System;

namespace Func02

{

class Program

{

/* static void Main(string[] args)

{

int i;

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

{

string text = "строка " + Convert.ToString(i);

Console.WriteLine("{0}", text);

}

Console.WriteLine("вывод текста в цикле: {0}", text);//ошибка

}

*/

static void Main(string[] args)

{

int i;

string text;

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

{

text = "строка " + Convert.ToString(i);

Console.WriteLine("{0}", text);

}

Console.WriteLine("вывод текста в цикле: {0}", text);//ошибка

/* text - ссылка, которая инициализируется внутри блока, а при

выходе из блока выделенная в нем ОП не доступна (освобождается сборщиком мусора).*/

}

/*

static void Main(string[] args)

{

int i;

string text = " ";

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

{

text = "строка " + Convert.ToString(i);

Console.WriteLine("{0}", text);

}

Console.WriteLine("вывод текста в цикле: {0}", text);

Console.ReadKey();

}

*/

}

}

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

Перегрузка функций

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

Функции

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

Определение функции состоит из следующих элементов:

  • Два ключевых слова: static и типа возвращаемого значения (void, если ничего не возвращает).
  • Имя функции, за которым следуют круглые скобки, внутри которых размещаются параметры.
  • Заключенный в фигурные скобки блок кода, который подлежит выполнению.

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

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

При использовании параметра-значения в функцию передается копия значения переменной из вызывающей функции и ее изменение в функции не изменяет значение переменной в вызывающей функции.

При использовании параметров-ссылок и выходных параметров в функцию передается адрес переменной из вызывающей функции, что дает ей возможность доступа к самой переменной. Параметры-ссылки и выходные параметры используют модификаторы ref и out перед параметром как в определении, так и в вызове функции.

Существуют два важных отличия:

  • В качестве параметра ref применять неинициализированную переменную нельзя, а в качестве out – можно.
  • Параметр out должен трактоваться функцией, которая его использует, как не имеющий присвоенного значения.

Преимущества использования функций по сравнению с многократным использованием повторяющегося кода:

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

Предлагаемое рассмотрение функций охватывает следующие ключевые моменты:

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

Любой проект консольного или оконного типа должен иметь по крайней мере одну точку входа, определяемую статической функцией Main(). Каждая функция, в том числе и функция Main(), должна принадлежать какому-нибудь классу, т.е. быть методом. Функция Main() объявляется как статический метод, не требующий создания экземпляра (Instance) класса для ее вызова. (Внимание! В приложении, имеющем несколько классов, функция Main() может входить в несколько из них. В этом случае для определения единственной точки входа нужно определить через окно свойств проекта, какой именно класс будет стартовым для данного приложения.)

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

Глобальные переменные

Скомпилируйте и выполните (по очереди) все фрагменты программ Пример 1 и Пример 2 (включая закомментированные) и объясните результаты.

Пример 1.

//Область видимости переменных в функциях

using System;

namespace Func01

{

class Program

{

/* static void Write()

{

Console.WriteLine("myString = {0}",myString);//ошибка

}

static void Main(string[] args)

{

string myString = "String defined in Main()");//не используется

Write();

Console.ReadKey();

}

*/

//описать последовательность выполнения операторов

/* static void Write()

{

string myString = "строка из Write()";//локальная

Console.WriteLine("\n это Write()!");

Console.WriteLine("myString = {0}", myString);

}

static void Main(string[] args)

{

string myString = "строка из Main()";//локальная переменная

Write();

Console.WriteLine("\n это Main()");

Console.WriteLine("myString = {0}", myString);

Console.ReadKey();

}

*/

static string myString;//глобальная переменная

static void Write()

{

string myString = "строка из Write()";//локальная переменная

Console.WriteLine("\n это Write()");

Console.WriteLine("Local myString = {0}", myString);

Console.WriteLine("Global myString = {0}", Program.myString);

}

static void Main(string[] args)

{

string myString = "строка из Main()";//локальная переменная

Program.myString = "Global string";

Write();

Console.WriteLine("\n это Main()");

Console.WriteLine("Local myString = {0}", myString);

Console.WriteLine("Global myString = {0}", Program.myString);

Console.ReadKey();

}

}

}

//------------------------------------------------------------------------

Пример 2

//область видимости переменных в других структурах

using System;

namespace Func02

{

class Program

{

/* static void Main(string[] args)

{

int i;

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

{

string text = "строка " + Convert.ToString(i);

Console.WriteLine("{0}", text);

}

Console.WriteLine("вывод текста в цикле: {0}", text);//ошибка

}

*/

static void Main(string[] args)

{

int i;

string text;

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

{

text = "строка " + Convert.ToString(i);

Console.WriteLine("{0}", text);

}

Console.WriteLine("вывод текста в цикле: {0}", text);//ошибка

/* text - ссылка, которая инициализируется внутри блока, а при

выходе из блока выделенная в нем ОП не доступна (освобождается сборщиком мусора).*/

}

/*

static void Main(string[] args)

{

int i;

string text = " ";

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

{

text = "строка " + Convert.ToString(i);

Console.WriteLine("{0}", text);

}

Console.WriteLine("вывод текста в цикле: {0}", text);

Console.ReadKey();

}

*/

}

}

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

Использование параметров и возвращаемых значений

Наши рекомендации