Как называется оператор который придает ячейке оперативной памяти которой является переменная ответ

Обновлено: 04.07.2024

При выполнении программы каждая используемая в ней переменная получает свой адрес в оперативной памяти. Программисту не нужно заботиться о механизме распределения адресов, это делается автоматически. Машина сама ищет свободное место в памяти и выделяет в ней место для переменных. В Турбо-Паскале есть два способа распределения памяти: статический и динамический. При статическом распределении всем объявленным в программе переменным в сегменте данных выделяются фиксированные участки оперативной памяти. В связи с этим использование заранее не объявленных переменных не допускается. При динамическом распределении памяти имеется возможность создавать новые, не объявленные заранее, переменные и размещать их на свободные участки в динамической области оперативной памяти. Динамическая переменная не указывается явно в описаниях переменных и к ней нельзя обратиться по имени. Это достигается за счет использования указателей.

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

123

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

Описание указателей

Указатель объявляется с помощью символа каре (^), за которым записывается идентификатор типа динамической переменной:

1)

2)

В этом случае переменные A, B, C являются указателями на переменные типа Integer. Для обращения к значениям этих переменных служат идентификаторы A^, B^, C^, т.е. имя переменной и знак каре.

Кроме того, указатель может быть объявлен явно следующим образом:

3)

Над указателями не определено никаких операций, кроме проверки на равенство и неравенство.

Для динамических переменных (A^, B^, C^) допустимы все те же операции, что и над обычными переменными данного типа.

Переменные типа указатель не могут быть элементами списка ввода-вывода.

  • Стандартные процедуры и функции для работы с указателями

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

  1. Любым действиям с динамической переменной должна предшествовать процедура ее размещения в ОЗУ. Эта процедура имеет вид: New (Varp:Pointer). Она создает новую динамическую переменную, присваивая указателю p значение ее адреса в ОЗУ. При этом динамической переменной отводится блок памяти, соответствующий размеру типа, с которым объявлен указатель p.
  2. Когда в ходе вычислительного процесса переменная становится ненужной, ее следует удалить. Это осуществляется процедурой Dispose (Varp:Pointer). Данная процедура освобождает память, занятую динамической переменной, делая значение ее указателя неопределенным.

Все изложенное пока не дает ответа на вопрос: «А зачем это нужно?» Отвечаем. Динамические переменные используются в основном в двух ситуациях:

  • для работы с массивами больших размеров;
  • для работы с особыми структурами переменных размеров, которые получили название динамических структур данных.

Массив указателей (см. Алексеев стр. 227-232)

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

Предположим, мы хотим запомнить как можно больше длинных строк символов. Размер строки – 256 байт, поэтому их предельное количество в статической памяти равно 64*1024/256=256.

Для хранения большего числа строк разместим в статической памяти лишь указатели на них, а сами строки перенесем в динамическую память. Заметим, что размер одного указателя – 4байта.

Указатели чаще всего используются для работы с динамическими массивами памяти, которые представляют собой массивы переменной длины, память под которые может выделяться и изменяться в процессе выполнения программы, как при каждом новом запуске программы, так и в разных ее частях. Обращение к i-му элементу динамического массива x имеет вид x^[i].

При работе с динамическими переменными необходимо соблюдать следующий порядок работы:

  1. описать указатели;
  2. распределить память;
  3. обработать динамический массив;
  4. освободить память.

Понятие динамического массива можно распространить и на матрицы. Динамическая матрица представляет собой массив указателей, каждый из которых адресует одну строку (или столбец). Рассмотрим описание динамической матрицы. Пусть есть типы данных massiv и указатель на него din_massiv:

Динамическая матрица X будет представлять собой массив указателей:

Работать с матрицей необходимо следующим образом:

  1. определить ее размеры (пусть N – число строк, M – число столбцов);
  2. выделить память под матрицу:

Каждый элемент статического массива X[i] – указатель на динамический массив, состоящий из M элементов типа real. В статическом массиве X находится N указателей.

  1. для обращения к элементу динамической матрицы, расположенному в i-той строке и j-м столбце, следует использовать следующую конструкцию: X[i]^[j];
  2. после завершения работы с матрицей необходимо освободить память:

При хранении большого количества однотипных данных можно использовать динамические массивы, но у них есть существенные недостатки:

  • размер динамического массива постоянен;
  • невозможно добавление элементов в середину массива.

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

Динамические структуры данных

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

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

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

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

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

Другое дело — живая очередь (в магазине, железнодорожной кассе). Коли­чество человек в очереди постоянно меняется, люди приходят и уходят, но никакой неразберихи не происходит — каждый знает, за кем он стоит. Об­разуется связанная цепочка людей. Очевидно, кому-то из стоящих в очереди и пришла идея создания динамических структур данных.

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

Связанный список — это такая структура данных, эле­ментами которой служат записи одного и того же формата, связанные друг с другом с помощью указателей, расположенных в самих элементах. Эле­менты списка часто называются его узлами.

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

В содержательной части хранятся данные, ради которых и создается список.

Если указующая часть хранит адрес одного соседнего элемента списка, то
такой список называется односвязным, или однонаправленным. Поле указате­ля последнего элемента содержит специальный признак Nil (признак конца списка). Для каждого элемента (кроме последнего) имеется единственный следующий элемент, поэтому связанные списки иногда называют линейными. Логическая структура односвязного списка представлена ниже.

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

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

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

Перечислим типовые дейст­вия со списками:

  • добавить новый узел непосредственно перед заданным узлом;
  • удалить заданный узел;
  • объединить два (или более) линейных списка в один список;
  • разбить линейный список на два (или более) списка;
  • сделать копию списка;
  • выполнить сортировку узлов списка в возрастающем порядке по некото­рым полям в узлах;
  • найти в списке узел с заданным значением в некотором поле.

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

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

Элемент Описание
item, pitem Тип для одного элемента списка (запись) и указателя на него
data Поле данных (информационная часть элементов списка)
next,prev Указатели следующего, предыдущего элементов (указующая часть)
head, top Указатели на первыйи последний элемент списка
pl,p2 Рабочие указатели

Опишем тип одного элемента односвязного списка и указателя на этот эле­мент:

Обратите внимание на описание — это единственный разрешенный случай, когда тип используется до объявления (item). Очевидно, разработчики ком­пилятора сделали исключение ввиду особой важности списковых структур.

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

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

В примере реализованы две основные операции со стеком: добавление и удаление элементов. Для решения задачи потребовалось всего два указателя типа pitem. Один из них (top) всегда указывает на вершину стека, второй (p) – рабочий указатель, предназначенный для временного хранения адресов различных элементов. Обратите внимание на типовую процедуру вывода списка при помощи цикла while. Стандартное действие p:= p^ . prev; означает переход к следующему элементу стека (для стека правильнее назвать этот элемент не следующим, а предыдущим, т.к. он был помещен в стек раньше). Поэтому элементы стека можно вывести только в порядке, обратном тому, в котором они выводились.

Подведем итоги. Итак, связные списки и массивы – две основные структуры в оперативной памяти, которые используются для обработки данных. Сравним их между собой, выделив главные моменты:

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

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

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

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

В логическом программировании принят другой, алгебраический подход. Обычного («разрушающего») присвоения здесь нет. Существуют только неизвестные, которые ещё не вычислены, и соответствующие идентификаторы для обозначения этих неизвестных. Программа только определяет их значения, сами они постоянны. Конечно, в реализации программа производит запись в память, но языки программирования этого не отражают, давая программисту возможность работать с идентификаторами постоянных значений, а не с переменными.

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

Определение присваивания

Общий синтаксис простого присваивания выглядит следующим образом:

«Выражение слева» должно после вычисления привести к местоположению объекта данных, к целевой переменной, идентификатору ячейки памяти, в которую будет производиться запись. Такие ссылки называются «левосторонними значениями» (англ. lvalue ). Типичные примеры левостороннего значения — имя переменной ( x ), путь к переменной в пространстве имён и библиотеках ( Namespace.Library.Object.AnotherObject.Property ), путь к массиву с выражением на месте индекса ( this.a[i+j*k] ), но ниже в данной статье приведены и более сложные варианты.

«Выражение справа» должно обозначать тем или иным способом ту величину, которая будет присвоена объекту данных. Таким образом, даже если справа стои́т имя той же переменной, что и слева, интерпретируется оно иначе — такие ссылки называются «правосторонними значениями» (англ. rvalue ). Дальнейшие ограничения на выражение накладывает используемый язык: так, в статически типизированных языках оно должно иметь тот же тип, что и целевая переменная, либо тип, приводимый к нему; в некоторых языках (например, Си или a=b=c ).

В роли оператора присваивания в языках программирования чаще всего выступают = , := или ← . Но специальный синтаксис может и не вводится — например, в

Данная запись эквивалентна вызову функции. Аналогично, в КОБОЛе старого стиля:

Алгоритм работы оператора присваивания

Символ присваивания

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

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

Выбор символа оператора равенства в языке при использовании = как присваивания решается:

  • Введением нового символа языка для оператора проверки равенства.

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

  • Использованием этого же символа, значение определяется в зависимости от контекста.

Например, в выражении языка ПЛ/1:

переменной А присваивается булевское значение выражения отношения В = С . Такая запись приводит к снижению читабельности и редко используется.

Семантические особенности

Далеко не всегда «интуитивный» (для программистов императивных языков) способ интерпретации присваивания является единственно верным и возможным.

Бывает, по используемому синтаксису, в императивных языках невозможно понять как реализуется семантика присваивания, если это, явно, не определено в языке.

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

Следствием чего можно провести присваивание данных, сформированных(расположенных) далеко от операции присваивания.

Рассмотрим простой пример для вышесказанного:

или так то же самое(семантически):

Неоднозначность присваивания

Это можно понять как «результат вычисления 2+1 (то есть 3) присваивается переменной X » или как «операция 2+1 присваивается переменной X ». Если язык статически типизирован, то двусмысленности нет, она разрешается типом переменной X («целое число» или «операция»). В языке Пролог типизация динамическая, поэтому существуют две операции присвоения: is — присвоение эквивалентного значения и = — присвоение образца. В таком случае:

Первая последовательность будет признана верной, вторая — ложной.

Семантика ссылок

При работе с объектами больших размеров и сложной структуры многие языки используют так называемую «семантику ссылок». Это означает, что присвоения в классическом смысле не происходит, но считается, что значение целевой переменной располагается на том же месте, что и значение исходной. Например (

После этого b будет иметь значение [1, 1000, 3] — просто потому, что фактически его значение — это и есть значение a . Число ссылок на один и тот же объект данных называется его мощностью, а сам объект погибает (уничтожается или отдаётся сборщику мусора), когда его мощность достигает нуля. Языки программирования более низкого уровня (например, Си) позволяют программисту явно управлять тем, используется ли семантика указателей или семантика копирования.

Подмена операции

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

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

Расширения конструкции присваивания


Конструкции присвоения в различных языках программирования

Поскольку операция присвоения является широко используемой, разработчики языков программирования пытаются разработать новые конструкции для упрощённой записи типичных операций (добавить в язык так называемый «синтаксический сахар»). Кроме этого в низкоуровневых языках программирования часто критерием включения операции является возможность компиляции в эффективный исполняемый код. [2] Особенно известен данным свойством язык Си.

Множественные целевые объекты

Одной из альтернатив простого оператора является возможность присвоения значения выражения нескольким объектам. Например, в языке ПЛ/1 оператор

одновременно присваивает нулевое значение переменным SUM и TOTAL . В языке Ада присвоение также является оператором, а не выражением, поэтому запись множественного присвоения имеет вид:

Аналогичное присвоение в языке

В отличие от ПЛ/1, Ады и Питона, где множественное присвоение считается только сокращённой формой записи, в языках Си, Лисп и других данный синтаксис имеет строгую основу: просто оператор присвоения возвращает присвоенное им значение (см. выше). Таким образом, последний пример — это на самом деле:

Строчка такого вида сработает в Си (если добавить точку с запятой в конце), но вызовет ошибку в Питоне.

Параллельное присваивание

Некоторые языки, например Руби и

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

запись с использованием параллельного присваивания «традиционное» присвоение: требует дополнительной переменной и трёх операций

Некоторые языки (например,

Условные целевые объекты

Некоторые языки программирования, например, C++ и

присвоит 0 переменной count1 если flag истинно и count2 , если flag ложно.

Другой вариант условного присваивания (Руби):

Данная конструкция присваивает переменной a значение только в том случае, если значение ещё не присвоено или равно false .

Составные операторы присваивания

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

Синтаксис составного оператора присваивания языка Си представляет собой объединение нужного бинарного оператора и оператора = . Например, следующие записи эквивалентны

Унарные операторы присваивания

В языке программирования Си и большинстве производных от него есть два специальных унарных (то есть имеющих один аргумент) арифметических оператора, представляющих собой в действительности сокращённые присваивания . Эти операторы сочетают операции увеличения и уменьшения на единицу с присваиванием. Операторы ++ для увеличения и -- для уменьшения могут использоваться как префиксные операторы (то есть перед операндами) или как постфиксные (то есть после операндов), означая различный порядок вычислений. Оператор префиксной инкрементации возвращает уже увеличенное значение операнда, а постфиксной — исходное.

Ниже приведён пример использования оператора инкрементации для формирования завершённого оператора присвоения

увеличение значения переменной на единицу эквивалентная расширенная запись

Хоть это и не выглядит присваивания, но таковым является. Результат выполнения приведённого выше оператора равнозначен результату выполнения присваивания .

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


Все переменные на языке Паскаль должны быть описаны в "голове" программы, в разделе VAR.


В программе строка VAR называется описанием переменных величин а и b. Описание начинается со служебного слова VAR (сокращение от английского variable - переменная). После него записываются имена всех переменных, встречающихся в программе с указанием через двоеточие типа значений, которые каждая переменная имеет право принимать.

СПРАВКА

Зачем нужно описание?

После того, как программист ввел программу в память, он приказывает компьютеру ее исполнить. Но компьютер при этом не сразу принимается выполнять программу, а сначала совершает компиляцию, то есть перевод программы с Паскаля на собственный машинный язык. (Часто вместо термина «компиляция» употребляют более общий термин «трансляция»). Во время компиляции компьютер производит некоторые подготовительные действия, одним из которых является отведение в памяти места под переменные величины, упомянутые в программе. При этом компьютер "рассуждает" так: Раз в программе упомянута переменная величина, значит она в каждый момент времени будет иметь какое-то значение, которое, хочешь не хочешь, надо помнить. Лучше, чтобы не спутаться, заранее отвести в памяти определенное место для запоминания текущего значения каждой переменной величины и только потом уже выполнять программу. Будем называть место, отведенное в памяти под данную переменную, ячейкой.

Что можно делать с переменными величинами, программируя на Паскале? Прежде всего, задавать компьютеру значение той или иной переменной величины. Это можно сделать при помощи нового оператора, который называется оператором присваивания .

Так, если необходимо чтобы переменная а имела значение 6 , то нужно записать а := 6 .

Знак := называется знаком присваивания , а сама запись а:=6 называется оператором присваивания. Говорят, что величине а присваивается значение 6 . С момента выполнения оператора а:=6 компьютер будет помнить, что а равно шести.

Справа от значка := в операторе присваивания можно писать не только числа, но и переменные величины, и выражения.

Например, после выполнения следующего фрагмента программы:

компьютер будет знать, то a равно 10 , b равно 10 , y равно 21 .

Еще несколько примеров:

Задание 1: запишите заданный фрагмент в виде программы, выполните ее и запишите в тетради, что выводится на экране.

Сравним две программы решения задачи:

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

ReadLn читается "рид'лайн", переводится "читай строку". Он приказывает компьютеру остановиться и ждать, когда человек введет с клавиатуры определенную информацию, после чего продолжить работу. В частности, ReadLn (a,b) будет ждать ввода двух целых чисел.

Если первая программа после запуска будет работать без остановки до самого конца и без хлопот выдаст результат, то вторая программа на операторе ReadLn остановится и будет ждать. Во время этого ожидания человек должен на клавиатуре набрать число 20 (так как первым в списке оператора ReadLn стоит a ), затем нажать клавишу пробела, затем набрать 16 и нажать клавишу Enter. В соответствии с этим компьютер сразу же после нажатия Enter прекращает ожидание и прежде всего направляет число 20 в память, в ячейку a , число же 16 - в ячейку b . На этом он считает выполнение оператора ReadLn законченным и переходит к следующему оператору - WriteLn. В результате будет напечатано число 36.

Таким образом, обе программы делают одно и то же. Зачем же тогда применять ReadLn вместо оператора присваивания? Ведь первая программа понятней, да и работает без остановки.

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

Для вывода данных из оперативной памяти на экран монитора используется оператор вывода write:


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

Произвольный набор символов, заключенный в апострофы, считается строковой константой. Строковая константа может содержать любые символы, набираемые на клавиатуре.

  1. на экран выводятся символы, заключенные в апострофы: s=
  2. на экран выводится значение переменной, хранящееся в ячейке оперативной памяти с именем s.

Если значение переменной s равно 15 и она имеет целочисленный тип, то на экране появится: s=15.

Если значение переменной s равно 15, но она имеет вещественный тип, то на экране появится: s=l.5Е+01.

При выполнении оператора вывода все элементы списка вывода печатаются непосредственно друг за другом. Так, в результате работы оператора write (1, 20, 300) на экран будет выведена последовательность цифр 120300, которая будет восприниматься нами как число 120300, а не как три отдельные числовые константы. Сделать выводимые данные более доступными для восприятия можно разными способами:


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

  1. общее количество позиций, отводимых под число;
  2. количество позиций в дробной части числа.


При выполнение нового оператора write вывод продолжается в той же строке. Чтобы осуществить переход к новой строке, используется оператор writeln. Других различий между операторами write и writeln нет.

4.2.2. Первая программа на языке Паскаль

Пользуясь рассмотренными операторами, составим программу, вычисляющую длину окружности и площадь круга радиуса 5,4 см.

Исходными данными в этой задаче является радиус: r — 5,4 см. Результатом работы программы должны быть величины С — длина окружности и S — площадь круга. С, S и r — величины вещественного типа.

Исходные данные и результаты связаны соотношениями, известными из курса математики: С = 2πr, S = πr + . Программа, реализующая вычисления по этим формулам, будет иметь вид:


Эта программа верна и решает поставленную задачу. Запустив её на выполнение, вы получите следующий результат:


И всё-таки составленная нами программа имеет существенный недостаток: она находит длину окружности и площадь круга для единственного значения радиуса (5,4 см).

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

4.2.3. Ввод данных с клавиатуры

Для ввода в оперативную память значений переменных используется оператор ввода read:


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

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

var i, j: integer; x: real; a: char;

Присвоим переменным i, j, x, а значения 1, 0, 2.5 и 'А'. Для этого воспользуемся оператором read (i, j, x, a) и организуем входной поток одним из следующих способов:


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

Для ввода данных с клавиатуры можно также использовать оператор readln, который отличается от оператора read только тем, что после его выполнения курсор переходит на новую строку.


Результат работы усовершенствованной программы:


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

Самое главное

Для ввода в оперативную память значений переменных используются операторы ввода read и readln.

Для вывода данных из оперативной памяти на экран монитора используются операторы вывода write и writeln.

Ввод исходных данных и вывод результатов должны быть организованы понятно и удобно; это обеспечивает дружественность пользовательского интерфейса.

Читайте также: