Методы (Руководство по программированию на C#)
Метод — это блок кода, содержащий ряд инструкций. Программа инициирует выполнение инструкций, вызывая метод и указывая все аргументы, необходимые для этого метода. В C# все инструкции выполняются в контексте метода.
Метод Main является точкой входа для каждого приложения C# и вызывается общеязыковой средой выполнения (CLR) при запуске программы. В приложении, использующем инструкции верхнего уровня, метод Main создается компилятором и содержит все инструкции верхнего уровня.
В этой статье рассматриваются названные методы. Дополнительные сведения об анонимных функциях см. в статье Лямбда-выражения.
Сигнатуры методов
Методы объявляются в классе, структуре или интерфейсе путем указания уровня доступа, такого как public или private , необязательных модификаторов, таких как abstract или sealed , возвращаемого значения, имени метода и всех параметров этого метода. Все эти части вместе представляют собой сигнатуру метода.
Тип возврата метода не является частью сигнатуры метода в целях перегрузки метода. Однако он является частью сигнатуры метода при определении совместимости между делегатом и методом, который он указывает.
Параметры метода заключаются в скобки и разделяются запятыми. Пустые скобки указывают, что параметры методу не требуются. Этот класс содержит четыре метода:
abstract class Motorcycle < // Anyone can call this. public void StartEngine()* Method statements here */ > // Only derived classes can call this. protected void AddGas(int gallons) < /* Method statements here */ >// Derived classes can override the base class implementation. public virtual int Drive(int miles, int speed) < /* Method statements here */ return 1; >// Derived classes must implement this. public abstract double GetTopSpeed(); >
Доступ к методу
Вызов метода в объекте аналогичен доступу к полю. После имени объекта добавьте точку, имя метода и круглые скобки. Аргументы перечисляются в этих скобках и разделяются запятыми. Таким образом, методы класса Motorcycle могут вызываться, как показано в следующем примере:
class TestMotorcycle : Motorcycle < public override double GetTopSpeed() < return 108.4; >static void Main() < TestMotorcycle moto = new TestMotorcycle(); moto.StartEngine(); moto.AddGas(15); moto.Drive(5, 20); double speed = moto.GetTopSpeed(); Console.WriteLine("My top speed is ", speed); > >
Параметры и аргументы метода
Определение метода задает имена и типы всех необходимых параметров. Когда вызывающий код вызывает метод, он предоставляет конкретные значения, называемые аргументами, для каждого параметра. Аргументы должны быть совместимы с типом параметра, но имя аргумента (если есть), используемое в вызывающем коде, не обязательно должно совпадать с именем параметра, указанным в методе. Например:
public void Caller() < int numA = 4; // Call with an int variable. int productA = Square(numA); int numB = 32; // Call with another int variable. int productB = Square(numB); // Call with an integer literal. int productC = Square(12); // Call with an expression that evaluates to int. productC = Square(productA * 3); >int Square(int i) < // Store input argument in a local variable. int input = i; return input * input; >
Передача по ссылке и передача по значению
По умолчанию при передаче в метод экземпляра типа значения вместо самого этого экземпляра передается его копия. Поэтому изменения в аргументе не оказывают влияния на исходный экземпляр в вызывающем методе. Чтобы передать экземпляр типа значения по ссылке, используйте ключевое слово ref . Дополнительные сведения см. в разделе Передача параметров типа значения.
При передаче в метод объекта ссылочного типа передается ссылка на этот объект. То есть метод получает не сам объект, а аргумент, который указывает расположение объекта. При изменении члена объекта с помощью этой ссылки это изменение отражается в аргументе в вызывающем методе, даже если объект передается по значению.
Ссылочный тип создается с помощью ключевого слова class , как показано в следующем примере.
public class SampleRefType
Теперь, если передать объект, основанный на этом типе, в метод, то будет передана ссылка на объект. В следующем примере объект типа SampleRefType передается в метод ModifyObject :
public static void TestRefType() < SampleRefType rt = new SampleRefType(); rt.value = 44; ModifyObject(rt); Console.WriteLine(rt.value); >static void ModifyObject(SampleRefType obj)
В этом примере, в сущности, делается то же, что и в предыдущем примере, — аргумент по значению передается в метод. Но поскольку здесь используется ссылочный тип, результат будет другим. В данном случае в методе ModifyObject изменено поле value параметра obj , а также изменено поле value аргумента, rt в методе TestRefType . В качестве выходных данных метод TestRefType отображает 33.
Дополнительные сведения о передаче ссылочных типов по ссылке и по значению см. в разделах Передача параметров ссылочного типа и Ссылочные типы.
Возвращаемые значения
Методы могут возвращать значение вызывающему объекту. Если тип возврата, указываемый перед именем метода, не void , этот метод может возвращать значение с помощью оператора return . Инструкция с ключевым словом return , за которым следует значение, соответствующее типу возврата, будет возвращать это значение объекту, вызвавшему метод.
Значение можно вернуть вызывающему объекту по значению или по ссылке. Значения возвращаются вызывающему объекту по ссылке, если ключевое слово ref используется в сигнатуре метода и указывается после каждого ключевого слова return . Например, следующая сигнатура метода и оператор return указывают, что метод возвращает переменную с именем estDistance вызывающему объекту по ссылке.
public ref double GetEstimatedDistance()
Ключевое слове return также останавливает выполнение метода. Если тип возврата — void , инструкцию return без значения по-прежнему можно использовать для завершения выполнения метода. Без ключевого слова return этот метод будет останавливать выполнение при достижении конца блока кода. Методы с типом возврата, отличным от void, должны использовать ключевое слово return для возврата значения. Например, в следующих двух методах ключевое слово return используется для возврата целочисленных значений.
class SimpleMath < public int AddTwoNumbers(int number1, int number2) < return number1 + number2; >public int SquareANumber(int number) < return number * number; >>
Чтобы использовать значение, возвращаемое из метода, вызывающий метод может применять сам вызов метода везде, где будет достаточно значения того же типа. Можно также назначить возвращаемое значение переменной. Например, следующие два примера кода достигают одной и той же цели.
int result = obj.AddTwoNumbers(1, 2); result = obj.SquareANumber(result); // The result is 9. Console.WriteLine(result);
result = obj.SquareANumber(obj.AddTwoNumbers(1, 2)); // The result is 9. Console.WriteLine(result);
Использование локальной переменной, в данном случае result , для сохранения значения является необязательным. Это может улучшить читаемость кода или может оказаться необходимым, если нужно сохранить исходное значение аргумента для всей области метода.
Чтобы использовать значение, возвращаемое по ссылке из метода, необходимо объявить локальную ссылочную переменную, если планируется изменение значения. Например, если метод Planet.GetEstimatedDistance возвращает значение Double по ссылке, можно определить его как локальную ссылочную переменную с использованием кода следующего вида:
ref double distance = ref Planet.GetEstimatedDistance();
Возвращать многомерный массив из метода M , который изменяет содержимое массива, необязательно, если вызывающая функция передает массив в M . В целях оптимизации можно возвращать полученный массив из M или функциональный поток значений, однако это необязательно. Это связано с тем, что C# передает все ссылочные типы по значению, а значение ссылки на массив представляет собой указатель на массив. В методе M любые изменения содержимого массива отслеживаются любым кодом, имеющим ссылку на массив, как показано в приведенном ниже примере:
static void Main(string[] args) < int[,] matrix = new int[2, 2]; FillMatrix(matrix); // matrix is now full of -1 >public static void FillMatrix(int[,] matrix) < for (int i = 0; i < matrix.GetLength(0); i++) < for (int j = 0; j < matrix.GetLength(1); j++) < matrix[i, j] = -1; >> >
Асинхронные методы
С помощью функции async можно вызывать асинхронные методы, не прибегая к использованию явных обратных вызовов или ручному разделению кода между несколькими методами или лямбда-выражениями.
Если пометить метод с помощью модификатора async, можно использовать в этом методе инструкцию await. Когда управление достигает выражения await в асинхронном методе, управление возвращается вызывающему объекту и выполнение метода приостанавливается до завершения выполнения ожидающей задачи. После завершения задачи выполнение в методе может быть возобновлено.
Асинхронный метод возвращается в вызывающий объект, когда он встречает первый ожидаемый объект, выполнение которого еще не завершено, или когда выполнение асинхронного метода доходит до конца — в зависимости от того, что происходит раньше.
В следующем примере метод Main служит примером асинхронного метода с типом возврата Task. Он переходит к методу DoSomethingAsync и, поскольку он выражается в одной строке, он может опустить ключевые слова async и await . Поскольку DoSomethingAsync является асинхронным методом, задача для вызова DoSomethingAsync должна быть ожидаемой, как показывает следующая инструкция: await DoSomethingAsync(); .
class Program < static Task Main() =>DoSomethingAsync(); static async Task DoSomethingAsync() < TaskdelayTask = DelayAsync(); int result = await delayTask; // The previous two statements may be combined into // the following statement. //int result = await DelayAsync(); Console.WriteLine($"Result: "); > static async Task DelayAsync() < await Task.Delay(100); return 5; >> // Example output: // Result: 5
Асинхронный метод не может объявить все параметры ref или out , но может вызывать методы, которые имеют такие параметры.
Определения текста выражений
Часто используются определения методов, которые просто немедленно возвращаются с результатом выражения или которые имеют единственную инструкцию в тексте метода. Для определения таких методов существует сокращенный синтаксис с использованием => :
public Point Move(int dx, int dy) => new Point(x + dx, y + dy); public void Print() => Console.WriteLine(First + " " + Last); // Works with operators, properties, and indexers too. public static Complex operator +(Complex a, Complex b) => a.Add(b); public string Name => First + " " + Last; public Customer this[long id] => store.LookupCustomer(id);
Если метод возвращает void или является асинхронным методом, то текст метода должен быть выражением инструкции (так же, как при использовании лямбда-выражений). Свойства и индексаторы должны быть только для чтения, и вы не должны использовать ключевое слово get метода доступа.
Итераторы
Итератор выполняет настраиваемую итерацию по коллекции, например по списку или массиву. Итератор использует инструкцию yield return для возврата всех элементов по одному. При достижении инструкции yield return текущее расположение в коде запоминается. При следующем вызове итератора выполнение возобновляется с этого места.
Итератор вызывается из клиентского кода с помощью инструкции foreach .
Дополнительные сведения см. в разделе Итераторы.
Спецификация языка C#
Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.
См. также
- Руководство по программированию на C#
- Система типов C#
- Модификаторы доступа
- Статические классы и члены статических классов
- Наследование
- Абстрактные и запечатанные классы и члены классов
- params
- out
- ref;
- Параметры методов
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
The .NET documentation is open source. Provide feedback here.
Обратная связь
Отправить и просмотреть отзыв по
Базовый синтаксис языка Python
программирования, работающий на всех распространённых операционных системах.
В настоящее время существует две версии языка Python: более старая и стремительно теряющая популярность версия 2 и современная версия 3. Мы будем использовать версию 3 данного языка. Именно её необходимо установить дома, скачав данную версию с сайта www.python.org.
Запустить интерпретатор python можно из командной строки:
python3
Будьте внимательны: команда python может запустить интерпретатор версии 2, с которым мы работать не будем. В системе Windows можно использовать пункт меню «Python (command line)».
Интерактивный режим
Откройте командную строку и напишите команду python3.
Вы увидите примерно следующее приглашение командной строки:
Python 3.10.6 (main, Aug 2 2022, 00:00:00) [GCC 12.1.1 20220507 (Red Hat 12.1.1-1)] on linux Type "help", "copyright", "credits" or "license" for more information. >>>
Вводите команды и наслаждайтесь результатом. А что можно вводить? Несколько примеров:
>>> 2 + 2 4 >>> 2 ** 100 1267650600228229401496703205376 >>> 'Hello' + 'World' 'HelloWorld' >>> 'ABC' * 10 'ABCABCABCABCABCABCABCABCABCABC'
Первая команда вычисляет сумму двух чисел, вторая команда вычисляет 2 в степени 100, третья команда выполняет операцию конкатенации («склеивания») для строк, а четвертая команда печатает строку ‘ABC’ , повторенную 10 раз.
Хотите закончить работу с питоном? Введите команду exit () (именно так, со скобочками, так как это — функция) или нажмите :python:Ctrl+D.
Программируемый режим
В предыдущей главе мы использовали Python для простых разовых вычислений, используя интерактивный режим. Теперь создадим программу и выполним её целиком.
a = 179 b = 197 c = (a ** 2 + b ** 2) ** 0.5 print (c)
Здесь мы используем переменные — объекты, в которых можно сохранять различные (числовые, строковые и прочие) значения. В первой строке переменной a присваивается значение 179 , затем переменной b присваивается значение 197 , затем переменной c присваивается значение арифметического выражения (a 2 + b 2 ) 1 ⁄ 2 , равного длине гипотенузы. После этого значение переменной c выводится на экран.
Упражнение №1: первая программа
Откройте произвольный текстовый редактор, например, gedit . Скопируйте туда текст программы, написанной выше. Сохраните текст в файле с именем hypot . py .
Запустите терминал, перейдите в каталог, где лежит файл hypot . py и выполните эту программу:
python3 hypot.py
Интерпретатор языка Python вместо интерактивного режима выполнит последовательность команд из файла.
При этом значения вычисленных выражений не выводятся на экран (в отличие от интерактивного режима), поэтому для того, чтобы вывести результат работы программы, то есть значение переменной c , нужна функция print () .
Базовый синтаксис языка Python 3
Типы данных
Итак, мы видим, что Python умеет работать как минимум с двумя видами данных — числами и строками. Числа записываются последовательностью цифр, также перед числом может стоять знак минус, а строки записываются в одинарных кавычках. 2 и ‘2’ — это разные объекты, первый объект — число, а второй — строка. Операция :python:+ для целых чисел и для строк работает по-разному: для чисел это сложение, а для строк — конкатенация.
Кроме целых чисел есть и другой класс чисел: действительные (вещественные числа), представляемые в виде десятичных дробей. Они записываются с использованием десятичной точки, например, 2.0 .
Определить тип объекта можно при помощи функции type :
>>> type(2) >>> type(‘2’) >>> type(2.0)
Обратите внимание: type является функцией, аргументы функции указываются в скобках после ее имени.
Операции с числами
Вот список основных операций для чисел:
- A + B — сумма;
- A — B — разность;
- A * B — произведение;
- A / B — частное;
- A ** B — возведение в степень:
- A // B — целочисленное деление;
- A % B — остаток от деления.
Полезно помнить, что квадратный корень из числа :python:x — это x ** 0.5 , а корень степени :python:n — это x ** ( 1 / n ) .
Есть также унарный вариант операции :python:-, то есть это операция с одним аргументом. Она возвращает число, противоположное данному. Например: — A .
В выражении может встречаться много операций подряд. Как в этом случае определяется порядок действий? Например, чему будет равно 1 + 2 * 3 ** 1 + 1 ? В данном случае ответ будет 8, так как сначала выполняется возведение в степень, затем — умножение, затем — сложение (соответствует математическому 1 + 2⋅3 1 + 1 ).
Более общие правила определения приоритетов операций такие:
- Выполняются возведения в степень справа налево, то есть 3 ** 3 ** 3 это 3 27 .
- Выполняются унарные минусы (отрицания).
- Выполняются умножения и деления слева направо. Операции умножения и деления имеют одинаковый приоритет.
- Выполняются сложения и вычитания слева направо. Операции сложения и вычитания имеют одинаковый приоритет.
Операции над строками
- A + B — конкатенация;
- A * n — повторение n раз, значение n должно быть целого типа.
Ветвление
Ветвление (или условная инструкция) в Python имеет следующий синтаксис:
if Условие: Блок_инструкций_1 else: Блок_инструкций_2
Блок_инструкций_1 будет выполнен, если Условие истинно. Если Условие ложно, будет выполнен Блок_инструкций_2 .
В условной инструкции может отсутствовать слово else и последующий блок. Такая инструкция называется неполным ветвлением. Например, если дано число x и мы хотим заменить его на абсолютную величину x , то это можно сделать следующим образом:
if x 0: x = -x print(x)
В этом примере переменной x будет присвоено значение — x , но только в том случае, когда x < 0 . А вот инструкция print ( x ) будет выполнена всегда, независимо от проверяемого условия.
Для выделения блока инструкций, относящихся к инструкции if или else , в языке Python используются отступы. Все инструкции, которые относятся к одному блоку, должны иметь равную величину отступа, то есть одинаковое число пробелов в начале строки. Рекомендуется использовать отступ в 4 пробела.
Вложенные условные инструкции
Внутри условных инструкций можно использовать любые инструкции языка Python, в том числе и условную инструкцию. Вложенное ветвление — после одной развилки в ходе исполнения программы появляется другая развилка. При этом вложенные блоки имеют больший размер отступа (например, 8 пробелов).
Примере программы, которая по данным ненулевым числам x и y определяет, в какой из четвертей координатной плоскости находится точка (x,y):
x = int(input()) y = int(input()) if x > 0: if y > 0: # x>0, y>0 print("Первая четверть") else: # x>0, y print("Четвертая четверть") else: if y > 0: # x0 print("Вторая четверть") else: # x <0, yprint("Третья четверть")
В этом примере мы использовали комментарии – текст, который интерпретатор игнорирует. Комментариями в Pythonе является символ # и весь текст после этого символа до конца строки. Желательно писать код так, чтобы комментарии были излишними, однако допускается писать их там, где возникают «призраки» (утверждения или теоремы, которые использованы при написании кода, но не следуют из самого кода). Однако код выше является плохим примером документации: комментарии врут, поскольку автором не учтены точки на осях.
Операторы сравнения
Как правило, в качестве проверяемого условия используется результат вычисления одного из следующих операторов сравнения:
| Оператор | Значение |
|---|---|
| Меньше — условие верно, если первый операнд меньше второго. | |
| > | Больше — условие верно, если первый операнд больше второго. |
| Меньше или равно — условие верно, если первый операнд меньше или равен второму. | |
| >= | Больше или равно — условие верно, если первый операнд больше или равен второму. |
| == | Равенство. Условие верно, если два операнда равны. |
Операторы сравнения в можно объединять в цепочки, например, a == b == c или 1
Тип данных bool
Операторы сравнения возвращают значения специального логического типа bool . Значения логического типа могут принимать одно из двух значений: True (истина) или False (ложь). Если преобразовать логическое True к типу int , то получится 1, а преобразование False даст 0. При обратном преобразовании число 0 преобразуется в False , а любое ненулевое число в True . При преобразовании str в bool пустая строка преобразовывается в False , а любая непустая строка в True .
Каскадные условные инструкции
Пример программы, определяющий четверть координатной плоскости, можно переписать, используя «каскадную» последовательность инструкцией if . elif . else :
x = int(input()) y = int(input()) if x > 0 and y > 0: print("Первая четверть") elif x 0 and y > 0: print("Вторая четверть") elif x 0 and y 0: print("Третья четверть") elif x > 0 and y 0: print("Четвертая четверть") else: print("Точка находится на осях или в центре координат.")
В такой конструкции условия if , . elif проверяются по очереди, выполняется блок, соответствующий первому из истинных условий. Если все проверяемые условия ложны, то выполняется блок else , если он присутствует. Обратите внимание, что таким образом мы чётче видим условия наступления случаев (нет «призраков»), а также отлавливаем ситуацию, когда точка не находится ни в одной из четвертей.
Цикл while
Цикл while («пока») позволяет выполнить одну и ту же последовательность действий, пока проверяемое условие истинно. Условие записывается до тела цикла и проверяется до выполнения тела цикла. Как правило, цикл while используется, когда невозможно определить точное значение количества проходов исполнения цикла.
Синтаксис цикла while в простейшем случае выглядит так:
while Условие: Блок_инструкций
При выполнении цикла while сначала проверяется условие. Если оно ложно, то выполнение цикла прекращается и управление передается на следующую инструкцию после тела цикла while . Если условие истинно, то выполняется инструкция, после чего условие проверяется снова и снова выполняется инструкция. Так продолжается до тех пор, пока условие будет истинно. Как только условие станет ложно, работа цикла завершится и управление передастся следующей инструкции после цикла.
Например, следующий фрагмент программы напечатает на экран всех целые числа, не превосходящие n:
a = 1 while a n: print(a) a += 1
Общая схема цикла while в данном случае для перебора всех подходящих значений такая:
a = начальное_значение while а_является_подходящим_числом: обработать_a перейти_к_следующему_a
Выведем все степени двойки, не превосходящие числа n:
a = 1 while a n: print(a) a *= 2
Цикл for
Цикл for может быть использован как более краткая альтернатива циклу while .
Для последовательного перебора целых чисел из диапазона [ 0 ; n ) можно использовать цикл for :
for i in range(10): print(i)
Этот код по выполняемым действиям полностью соответствуют циклу while :
i = 0 while i 10: print(i) i += 1
Можно задавать начальные и конечные значения для переменной цикла, а также шаг:
for i in range(20, 10, -2): print(i)
Аналогичный цикл while
i = 20 while i > 10: print(i) i -= 2
Контест №1
Программированию учатся на практике, поэтому в курсе каждую неделю будет контест. Контест — это набор задач с системой автоматической проверки решения на тестовых наборах данных. Для участия необходима регистрация на контест.
В первый раз вам придётся создать пользователя (логин и пароль обязательно запишите!), а также ввести некоторую регистрационную информацию: фамилию, имя, номер учебной группы. Пожалуйста, вводите реальные данные, иначе преподаватель не сможет учитывать ваши решения.
Попробуйте сдать решение первой задачи:
x, y = input().split() x, y = int(x), int(y) print(x + y)
Сайт построен с использованием Pelican. За основу оформления взята тема от Smashing Magazine. Исходные тексты программ, приведённые на этом сайте, распространяются под лицензией GPLv3, все остальные материалы сайта распространяются под лицензией CC-BY.
Программирование в «Эврике»
В цикле с условием while цикл выполняется, пока истинно задающее его условие. Поэтому этот цикл также иногда называют циклом «пока». Часто цикл while используется, когда невозможно заранее предсказать, сколько раз необходимо выполнить тело цикла. В повседневной жизни цикл while можно встретить в алгоритмах, вроде «Пока в пределах видимости есть машины, стоять на месте» или «Пока в ящике есть детали, достать деталь из ящика».
В следующей программе цикл while используется подобно циклу for для вывода на экран всех чисел от 1 до 10:
i=1 while iВ этой программе переменной i присваивается значение 1. Затем начинается цикл (ключевое слово while ) с проверяемым условием i
Как только проверяемое условие станет ложно (это произойдет, когда переменная i станет равна 11), цикл завершит работу и управление будет передано следующей инструкции после блока цикла. Поэтому после завершения цикла переменная i будет иметь значение 11.
В общем виде синтаксис цикла с условием в языке Питон такой:
while условие: инструкция 1 инструкция 2 . инструкция n
- Условие, определяющее, будет ли выполняться тело цикла. Это условие записывается после слова while и может быть произвольным арифметическим выражением, в котором должен быть хотя бы один из операторов == , != , < , >, = и могут использоваться логические операторы and , or , not . После условия ставится двоеточие.
- Тело цикла, состоящее из одной или нескольких инструкций, записанных с отступом одинаковой величины.
- Инструкции, изменяющие значения переменных, входящих в проверяемое условие. В рассмотренном примере это инструкция i=i+1 . Если бы этой инструкции не было, то значение переменной i не менялось бы и проверяемое условие всегда было бы истинным, что привело бы к бесконечному циклу. Для прерывания работы программы, попавшей в бесконечный цикл, используется комбинация клавиш Ctrl+C .
n=input("Введите натуральное число") i=0 while 2**iВ этом примере переменная i внутри цикла увеличивается на 1, пока значение 2**i не превосходит n . После окончания цикла величина 2**i будет больше n , и соответствующее значение i будет напечатано на экране. Внутри цикла могут быть различные другие инструкции, в том числе инструкции if , while и for . В этом случае говорят о вложенных циклах, или об условной инструкции, вложенной в цикл. Тело вложенного цикла выделяется от цикла, в который оно вложено, большей величиной отступа. Рассмотрим два примера. В первом примере программа печатает на экран все натуральные делители данного натурального числа n . Для этого используется цикл, в котором переменная i меняется от 1 до n , а внутри цикла проверяется условие, и если остаток от деления n на i равен 0, то печатается значение i :
n=input("Введите число, для которого необходимо вывести делители") i=1 while iВ следующем примере на экран печатается таблица умножения всех однозначных чисел. Для этого организовано два цикла: в одном переменная i меняется от 1 до 9, внутри этого цикла (то есть при каждом новом значении i ) переменная j также меняется от 1 до 9. В блоке вложенного цикла на экран печатаются значения переменных i , j и их произведение:
i=1 while i for i in range(1,10): for j in range(1,10): print i, "*", j, " heading">Инструкции управления цикломВ циклах
whileиforможно использовать две инструкции, управляющие циклом.Инструкция
breakпрерывает выполнение цикла. Управление передается на следующую инструкцию после тела цикла.Инструкция
continueпрерывает текущую итерацию цикла. Все инструкции после инструкцииcontinueдо конца блока цикла пропускаются. В циклеforпеременной, которая меняется в цикле, присваивается следующее значение из списка и цикл продолжает выполняться с новым значением переменной. В циклеwhileпроверяется условие, заданное в цикле и если оно истинно, то цикл продолжает выполняться с начала блока цикла.Например, допустим, что нам необходимо перебрать в цикле все натуральные числа, меньшие
nи не делящиеся на 3. Для этого можно перебрать все числа, проверить их остаток от деления на 3, и если число делится на 3, выполнить инструкциюcontinue, которая пропустит оставшиеся до конца цикла инструкции и перейдет к следующему числу:for in range(n): if i%3==0: continue print i # а далее выполняем прочие необходимые действияИнструкции break и continue следует использовать только внутри условных инструкций. Безусловные инструкции break и continue , как правило, бессмысленны. Также в циклах while и for можно указать else -блок после основного блока цикла. else -блок в циклах выполняется один раз после завершения работы цикла, но только в случае, если цикл не был прерван инструкцией break . Поясним это на программе, которая по введенному целому числу n>1 определяет, является ли оно простым или составным.
n=input("Введите целое число, больше 1 ") # 1 Считали число n for d in range(2, n): # 2 d меняется от 2 до n-1 if n % d == 0: # 3 Проверка: n делится на d? print n, "имеет делитель", d # 4 break # 5 Завершаем цикл for else: # 6 Это else-блок цикла print n, "простое число" # 7Поясним эту программу. После ввода с клавиатуры числа n в программе организовывается цикл по переменной d , принимающей значения от 2 до n-1 (строка 2). Далее в теле цикла проверяется, является ли d делителем n (строка 3). Если является делителем, то на экран выводится соответствующее сообщение (строка 4) и при помощи инструкции break завершается выполнение цикла (строка 5). После тела цикла for идет else -блок. То, что инструкция else (строка 6) относится к циклу for (строка 2), а не к инструкции if (строка 3), определяется по величине отступа перед инструкцией else : отступ перед ней такой же, как и перед инструкцией for . Поэтому если цикл не был прерван инструкцией break , то есть для числа n не будет найден нетривиальный делитель, то будет выполнен else -блок, то есть на экран будет напечатано сообщение о том, что n — простое число (строка 7).
Как называется инструкция которая определяет данные соответствующие переменной
сохраняет инструкцию и связанное с нею имя до конца текущей транзакции (т.е до последующей инструкции commit или rollback). Если вам потребуется выполнить ту же самую динамическую инструкцию позднее, во время другой транзакции, то придется подготавливать ее еще раз. В других СУБД это офаничение ослаблено, а подготовленная инсфукция сохраняется в течение всего сеанса подключения к базе данных. В стандарте SQL2 указано, что доступность подготовленной инсфукции за пределами текущей фанзакции зависит от реализации СУБД.
Инструкция prepare может быть использована для подготовки практически любой исполняемой инструкции DML или DDL, включая инсфукцию select. Инструкции SQL, которые являются директивами препроцессора (например, инсфукции whenever или declare cursor), конечно, не могут быть подготовлены, так как это не исполняемые инструкции.
Инсфукция execute, синтаксическая диафамма которой изображена на рис. ] 8 6, применяется только в динамическом SQL. Она дает СУБД команду выполнить инструкцию, подготовленную ранее посредством инструкции prepare. С помощью инструкции execute можно выполнить любую подготовленную инструкцию, за одним исключением. Как и инсфукция execute immediate, инструкция execute не может использоваться для выполнения инсфукции select, поскольку не имеет механизма обработки результатов запроса.
I-EXECUTE имя инструкции USING
DESCRIPTOR имя двскриптора
Рис. 18.6. Синтаксическая диаграмма инструкции EXECUTE
Если динамическая инсфукция, которая должна быть выполнена, содержит один или несколько маркеров парамефов, инсфукция execute должна передать в СУБД значения всех этих параметров. Это можно сделать двумя различными способами, описанными в двух последующих парафафах В стандарте SQL2 поддерживаются оба способа
Инструкция EXECUTE с базовыми переменными
Самый простой способ передать значения парамефОв - это задать список базовых переменных в предложении using. Инструкция execute подставляет соответствующие значения базовых переменных вместо маркеров параметров в подготовленном тексте инструкции. Таким образом, эти базовые переменные являются дтя Динамически выполняемой инсфукции входными базовыми переменными. Такой метод применяется в программе, представленной на рис. 18 4.
Число базовых переменных в предложении using должно соогветствовать числу маркеров парамефов в динамической инструкции, а типы переменных должны бьяь совместимыми с типами данных соответствующих парамефов Каждая базовая переменная может иметь согтутствующую переменную-индикатор Если во время выполнения ннсфукции execute какая-нибудь переменная-индикатор содержит офицательное значение, то соответствующему маркеру параметра присваивается значение null.
Инструкция EXECUTE, использующая область SQLDA
BTopoff способ передачи параметров заключается в применении специальной структуры, называемой областью данных SQL или сокращенно sqlda (SQL Data Area) Эта область используется для передачи параметров, когда во время написания профаммы неизвестны ни число передаваемых парамефов, ни их типы данных Пусть, например, вам необходимо так модифицировать профамму обновления таблиц, представленную на рис 18 4, чтобы пользователь получил возможность обновлять несколько столбцов Можно легко модифицировать профамму, чтобы она формировала инсфукцию Update с переменным числом обновляемых столбцов, но возникает проблема со списком базовых переменных в инсфукции execute он должен быть заменен списком переменной длины Область sqlda как раз обеспечивает способ задания такого списка
На рис 18 7 изображен формат области sqlda, используемой во всех СУБД компании IBM, включая DB2, которая определяет стандарт де-факто на динамический SQL В большинстве других СУБД используется аналогичный формат или очень близкий к нему В стандарте SQL2 описана похожая структура, которая называется область дескриптора SQL В ней хранится та же самая информация, и обе Сфуктуры играют одинаковую роль в динамической обработке инструкций Однако детали записи информации в область дескриптора и последующего извлечения этой информации весьма существенно различаются На практике предпочтение отдается структуре sqlda, поскольку она появилась задолго до стандарта SQL2
Область sqlda представляет собой структуру данных переменной длины, состоящую из двух отдельных частей
Постоянная часть располагается в начале области Ее поля идентифицируют Сфуктуру как область sqlda и задают размер данной конкретной области
Переменная часть представляет собой массив из одной или нескольких сфуктур sqlvar Когда область sqlda используется для передачи парамефов в инсфукцию execute, то каждому парамефу соответствует отдельная структура sqlvar
unsigned char sqldaid[8]; long sqldabc;
unsigned char *sqldata;
unsigned char data[30]
Рис 18 7 Область данных SQL (SQLDAj в СУБД компании IBM
Поля структуры sqlvar описывают данные, переданные инсфукции execute в виде значений парамефов
Поле sqltype содержит целочисленный код типа данных, который определяет тип передаваемого парамефа Например, в DB2 код 500 соответствует двухбайтовому целому числу, код 496 - четырехбайтовому целому числу, а код 448 - символьной сфоке переменной длины (см таблицу 18 1)
Поле sqllen задает длину передаваемых данных Оно будет содержать значение 2 для двухбайтового целого числа и 4 дпя четырехбайтового целого числа Когда в качестве параметра передается символьная строка, поле sqllen содержит число символов в строке
Поле sqldata является указателем на область данньа внутри профаммы, которая содержит значение параметра СУБД использует этот указатель, чтобы найти требуемые данные при выполнении динамической инсфукции SQL Поля sql-type и sqllen информируют СУБД о типе этих данных и их длине
Поле sqlind является указателем на двухбайтовое целое число, которое используется в качестве переменной-индикатора дпя данного парамефа СУБД проверяет переменную-индикатор, чтобы определить, не передается ли значение null Если переменная-индикатор для парамефа отсутствует, то в поле sqlind должно быть указано значение нуль
Другие поля в сфуктуре sqlvar не используются для передачи парамефов посредством инструкции execute Они служат для извлечения информации из базы данных, этот процесс рассмафивается ниже в настоящей главе
На рис 18 8 изображена профамма с динамическим SQL, в которой входные парамефы задаются с помощью области sqlda Программа обновляет таблицу salesreps, и пользователь может указать, какие столбцы будут обновляться Затем профамма выполняет цикл, в котором запращиваег у пользователя идентификатор служащего и новые значения для обновляемых столбцов Если в ответ на просьбу ввести новое значение пользователь вводит звездочку (*), профамма присваивает соответствующему столбцу значение null
Данная программа обновляет указанные пользователем столбцы таблицы SALESREPS Вначале она запрашивает у пользователя имена столбцов, которые будут обновляться, а затем в цикле запрашивает идентификатор служащего и новые значения для выбранных столбцов
exec sql include sqlca, exec sql include sqlda, exec sql begin declare section,
char stmtbuf[2001], exec sql end declare section,
/* в таблице SALESREPS шесть столбцов */
/* текст инструкции SQL */
