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

Предоплата всего

Подписываем
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Предоплата всего
Подписываем
Е.С. Охотников, Е.С. Охотникова
[0.1] Лабораторный практикум по дисциплине «Языки программирования» (Паскаль)
[0.1.1] Тюмень, 2008
[1] [1.1] Требования к лабораторной работе [1.2] Задания к лабораторной работе [1.2.1] Группа А [1.2.2] Группа В [1.2.3] Группа С [1.3] Теоретический материал и методические указания [1.3.1] Знакомство со средой программирования [1.3.2] Открытие и сохранение проекта [1.3.3] Запуск и завершение работы программы [1.3.4] Работа с русским алфавитом [1.3.5] Понятие переменной, стандартные типы данных [1.3.6] Оператор присваивания [1.3.7] Процедуры ввода вывода [1.3.8] Арифметические операции [1.3.9] Стандартные функции [1.3.10] Стандартные ошибки [1.4] Контрольные вопросы [1.5] Примерный вариант контрольной работы
[2] [2.1] Требования к лабораторной работе [2.2] Задания к лабораторной работе [2.2.1] Группа А [2.2.2] Группа В [2.2.3] Группа С [2.3] Теоретический материал и методические указания [2.3.1] Логический тип boolean [2.3.2] Логические операции [2.3.3] Полная форма условного оператора [2.3.4] Краткая форма условного оператора [2.3.5] Оператор выбора [2.4] Контрольные вопросы [2.5] Примерный вариант контрольной работы
[3] [3.1] Требования к лабораторной работе [3.2] Задания к лабораторной работе [3.2.1] Группа А [3.2.2] Группа В [3.2.3] Группа С [3.3] Теоретический материал и методические указания [3.3.1] Цикл с параметром [3.3.2] Цикл с предусловием [3.3.3] Цикл с постусловием [3.3.4] Связь цикла с параметром и цикла с предусловием [3.4] Контрольные вопросы [3.5] Примерный вариант контрольной работы
[4] [4.1] Требования к лабораторной работе [4.2] Задания к лабораторной работе [4.2.1] Группа А [4.2.2] Группа В [4.2.3] Группа С [4.3] Теоретический материал и методические указания [4.3.1] Объявление переменной типа одномерный массив [4.3.2] Обращение к элементу одномерного массива [4.3.3] Заполнение одномерного массива [4.3.4] Вывод одномерного массива на экран [4.3.5] Объявление переменной типа двумерный массив [4.3.6] Обращение к элементу двумерного массива [4.3.7] Заполнение двумерного массива [4.3.8] Вывод элементов двумерного массива на экран [4.4] Контрольные вопросы [4.5] Примерный вариант контрольной работы
[5] [5.1] Требования к лабораторной работе [5.2] Задания к лабораторной работе [5.2.1] Группа А [5.2.2] Группа В [5.2.3] Группа С [5.3] Теоретический материал и методические указания [5.3.1] Объявление и инициализация строковых переменных [5.3.2] Обращение к элементу строки [5.3.3] Процедуры и функции для работы со строками [5.3.4] Массивы строк [5.4] Контрольные вопросы [5.5] Примерный вариант контрольной работы
[6] [6.1] Требования к лабораторной работе [6.2] Задания к лабораторной работе [6.2.1] Группа А [6.2.2] Группа В [6.2.3] Группа С [6.3] Теоретический материал и методические указания [6.3.1] Тип множество [6.3.2] Операции над множествами [6.3.3] Заполнение множества с клавиатуры [6.3.4] Вывод множества на экран [6.3.5] Тип запись [6.3.6] Правила работы с переменными типа запись [6.3.7] Массивы переменных типа запись [6.4] Контрольные вопросы [6.5] Примерный вариант контрольной работы
[7] [7.1] Требования к лабораторной работе [7.2] Задания к лабораторной работе [7.2.1] Группа А [7.2.2] Группа В [7.2.3] Группа С [7.3] Теоретический материал и методические указания [7.4] Контрольные вопросы [7.5] Примерный вариант контрольной работы
[8]
[9]
[10] |
Введение
Лабораторный практикум предназначен для поддержки проведения практических занятий и самостоятельной работы студентов по дисциплине «Языки программирования». В практикум вошли темы, посвященные изучению основ программирования на языке Паскаль.
В каждой теме представлены задачи для написания программ, сгруппированные по степени сложности. Задания группы А предназначены для проверки знания сущности изучаемого понятия, его определение, установление его простейших связей с другими понятиями, а также умения решать практические задания «по образцу». Задания группы В направлены на проверку умения анализировать понятия и связи между ними, применять теоретические знания в стандартных ситуациях, а также в практической деятельности. Задания группы С предназначены на формирование глубокого владения понятийно-логическим аппаратом, умения анализировать понятия и связи и оперировать ими в нестандартных ситуациях. Каждое задание состоит из шести аналогичных вариантов. По выбору преподавателя обучаемому могут быть назначены или все варианты задания, или только некоторые из них.
Для повышения доли самостоятельной работы студентов в практикуме приведено большое количество разобранных примеров, аналогичных по сложности заданиям группы А. Ознакомление с ними позволит обучаемым выполнять задания лабораторных работ, по крайней мере, на базовом уровне сложности. Помимо этого представлены краткие теоретические сведения и методические указания, необходимые для решения заданий. Для самооценки знаний обучаемых в конце каждой темы предлагаются контрольные вопросы и пример варианта контрольной работы.
После выполнения лабораторной работы обучаемый должен:
Задания лабораторной работы должны быть выполнены в консольном приложении среды программирования Borland Delphi 7 (или следующих версиях) в отдельных проектах.
При выводе на экран вещественных значений следует применять форматированный вывод.
Задание №1
Найдите периметр:
Задание №2
Найдите площадь:
Задание №3
Задание должно быть выполнено с применением стандартных функций и операций языка программирования Паскаль.
Напишите программу для вычисления значения функции, x и t вводить с клавиатуры:
Задание №4
Найдите значения выражений:
Задание №5
Задание №6
Задание выполняется для всех вариантов полностью.
Дано трехзначное число. Найти:
Задание №1
Вычислите объем (все необходимые параметры следует вводить с клавиатуры):
Задание №2
Поменяйте местами значения переменных х и у с использованием дополнительной переменной.
Задание №3
Задание должно быть выполнено с применением стандартных функций и операций языка программирования Паскаль.
Напишите программу для вычисления значения функции, x и t вводить с клавиатуры:
Задание №4
Задание №5
Задание выполняется для всех вариантов полностью.
С начала суток прошло n секунд. Определить:
Задание №1
При выполнении задания не разрешается использовать функции power() и exp().
Вычислить за наименьшее количество операций
Задание №2
Поменяйте местами значения переменных х и у без использования дополнительной переменной.
Задание №3
Напишите программу для вычисления значения функции, x и t вводить с клавиатуры:
Задание №4
Найдите объем (значения всех необходимых параметров следует вводить с клавиатуры):
Задание №5
Задание выполняется для всех вариантов полностью.
Для того чтобы открыть среду программирования Borland Delphi 7, обычно нужно выбрать «Пуск Программы - Borland Delphi 7 Delphi 7», хотя в зависимости от настроек, заданных при установке Delphi 7, на разных компьютерах пути могут несколько отличаться.
Для создания нового консольного приложения нужно выбрать пункты главного меню среды программирования «File New - Other».
На экране отобразится следующее окно. На закладке «New» нужно выбрать элемент «Console Application».
На экране появится окно, которое содержит заготовку программы.
Жирным шрифтом выделены зарезервированные слова языка программирования Паскаль. Рассмотрим, что означает приведенный текст:
Все написанные в Delphi 7 программы принято называть проектами. По умолчанию новая программа будет называться Project1, Project2 и т.п. Это можно увидеть в заголовке окна консольного приложения на этапе разработки и в заголовке окна исполняемого приложения.
Для сохранения проекта нужно выбрать пункт главного меню «File Save Project As». На экране появится окно стандартного диалога для сохранения файла.
Название файла можно изменить. По умолчанию Delphi предлагает сохранить файл в папку С:\Program Files\Borland Delphi 7\Projects.
При сохранении проекта в действительности сохраняется не один файл, а несколько файлов с различными расширениями. Если требуется перенести проект на компьютер, на котором установлена Delphi 7, то достаточно оставить файл с расширением *.dpr, т.е. файл проекта.
Открыть проект также можно несколькими способами:
При первом запуске программы она может потребовать сохранения проекта, это зависит от настроек среды, при других настройках можно несколько часов работать над проектом, неоднократно его запуская, без сохранения. Во время работы рекомендуется периодически сохранять проект.
Пример 1.
Требуется вывести на экран фразу «My first program».
Информация выводится на экран с помощью операторов вывода write() или writeln(). Их отличия будут рассмотрены далее.
Все команды пишутся внутри тела программы, они отделяются друг от друга знаком «;». Принято каждую следующую команду начинать с новой строки. В скобках оператора writeln записывается то, что должно быть выведено на экран, текст должен быть заключен в одинарные кавычки. Второй оператор программы readln, в такой форме он выполняет функцию задержки экрана. Без его использования исполняемое приложение появится на экране на мгновение и закроется. Чтобы увидеть результаты работы программы и используется оператор readln. В этом случае программа закрывается только после того как пользователь нажал клавишу Enter на клавиатуре.
Программу можно запустить несколькими способами:
После запуска программы на экране появится следующее окно:
которое можно закрыть или соответствующей кнопкой заголовка окна, или нажатием клавиши Enter на клавиатуре.
Если же программа завершила свою работу с ошибкой, например:
В этом случае следует нажать кнопку «OК», затем, чтобы вернуться в среду разработки нужно выбрать пункт главного меню «Run Program Reset» или воспользоваться сочетанием клавиш «Ctrl+F2».
Стандартные настройки консольного приложения Delphi 7 не позволяют корректно работать с русскими буквами. Если же задание подразумевает работу с ними, нужно воспользоваться стандартными процедурами SetConsoleCP(1251); и SetConsoleOutputCP(1251);.
Обратите внимание, что для использования этих процедур нужно подключить модуль под названием Windows.
Далее следует запустить приложение, правой кнопкой мыши щелкнуть по заголовку окна, в появившемся контекстном меню выбрать пункт «Свойства».
В появившемся окне на закладке «Шрифт» нужно выбрать тип шрифта Lucida Console. Теперь русские буквы будут отображаться корректно.
Понятие модуля
Модуль автономно компилируемая программная единица, включающая в себя различные компоненты раздела описаний: типы, константы, переменные, процедуры и функции.
В отдельном модуле обычно описываются типы данных, реализация процедур и функций, относящихся к конкретной задаче или области. Например, существует модуль Math, содержащий описание более сложных математических функций (чем, например, sin(x)). Можно провести аналогию: в жизни вряд ли можно встретить учебник, содержащий информацию по всем, изучаемым в институте Математики и Компьютерных Наук дисциплинам (алгебре, физике, теории вероятности, русскому языку, философии и т.п.). Даже в рамках одного предмета можно выделить различные разделы, которым будут соответствовать различные учебники. Очевидно, если нужно узнать, что такое частная производная, будет гораздо проще искать определение в учебнике по математическому анализу, а за определением понятия «материя » обратиться к философскому словарю, чем искать нужный текст в огромной общей книге, а представьте, что эту книгу нужно постоянно носить с собой на все занятия.
Так и в программах, модули (кроме SysUtils, содержащего описание стандартных типов данных, процедур ввода вывода и др.) подключаются только по мере необходимости.
Параметры программы, значения которых могут изменяться в процессе ее выполнения, называются переменными. Переменные в языке программирования Паскаль объявляются в строго определенной части программы разделе объявления переменных. Этот раздел начинается с ключевого слова var («variable» в переводе с английского означает «переменная величина»). Раздел объявления переменных расположен перед телом программы. В примере объявлена одна переменная MyVar типа byte.
Тип данных определяет диапазон значений переменной (переменная MyVar может быть равна любому числу из диапазона 0..255), размер выделяемой памяти (здесь 1 байт) и операции, которые допустимы для данной переменной.
Запись var MyVar:byte; означает, что в памяти компьютера под эту переменную выделится ячейка размером 1 байт, в которой может быть размещено некоторое значение, а обращаться к этой ячейке можно через имя MyVar.
Обратите внимание, что в программе нельзя использовать имена переменных, которые не были объявлены в разделе var, иначе программа не сможет их интерпретировать.
После объявления переменной под нее выделяется соответствующего размера ячейка памяти, при этом содержание этой ячейки, вообще говоря, не определено. Хорошим стилем программирования считается явная инициализация переменной до ее первого использования. Считается, что компилятор языка программирования Паскаль инициализирует все глобальные переменные (т.е. описанные в разделе var основной программы) нулями. Но при изменении настроек компилятора такие переменные могут быть проинициализированы и произвольными значениями, кроме того не инициализируются нулями и локальные переменные (т.е. переменные, описанные внутри подпрограмм).
В программе может быть объявлено произвольное количество переменных различных типов.
Если требуется объявить несколько переменных одного типа данных, то их имена можно перечислить через запятую (как показано на рисунке). Имена переменных могут быть произвольными, при они должны отвечать правилам составления идентификаторов языка программирования Паскаль. Если по имени переменной можно понять ее назначение, то это считается хорошим стилем программирования. Например, переменную, предназначенную для накопления суммы переменных лучше назвать sum, чем просто х.
Присвоить переменной некоторое значение можно с помощью оператора присваивания, в языке программирования Паскаль он имеет вид « := ».
Запись MyVar:=5; читается: «переменной MyVar присвоить значение пять». Это означает, что теперь в ячейке памяти с именем MyVar записано значение 5 .
Переменной могут присваиваться различные значения и результаты вычисления выражений на протяжении всей программы.
Как уже упоминалось ранее, процедура writeln() предназначена для вывода информации на экран. С помощью процедуры writeln() на экран можно выводить текст (он должен быть заключен в одинарные кавычки) и значения переменных. Например, результатом выполнения оператора writeln(Моя программа); будет вывод на экран соответствующей строки, а результатом выполнения writeln(MyVar); - вывод значения переменной MyVar. Причем данная процедура может иметь произвольное количество параметров, которые следует перечислять через запятую. На рисунке ниже приведен результат выполнения программы
var MyVar:byte;
begin
MyVar:=5;
writeln('MyVar= ', MyVar);
readln;
end.
Текст, передаваемый в процедуру writeln(), выводится без изменения, а вместо имени переменной выводится ее значение.
Для вывода информации предназначена еще одна процедура write(). Результатом выполнения обеих процедур является вывод на экран параметров, указанных в скобках, только writeln() еще переводит курсор на новую строку. Сравните:
begin writeln('1'); writeln('2'); writeln('3'); readln; end. |
begin write('1'); write('2'); write('3'); readln; end. |
В языке программирования Паскаль существует две процедуры для ввода данных с клавиатуры: read() и readln(). Отличаются они тем, что read просто считывает информацию, а readln ее считывает вместе со знаком конца строки. Визуальных отличий, как при использовании write() и writeln() нет, но чаще используется процедура readln.
Запись readln(MyVar); означает, что число, введенное пользователем, поместиться в ячейке памяти с именем MyVar. При этом если пользователь введет данные, не являющиеся целым числом, то программа закончит свое выполнение с ошибкой.
При запуске программы
uses SysUtils,Windows;
var MyVar:byte;
begin
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
writeln('Введите число');
readln(MyVar);
writeln('Вы ввели число ', MyVar);
readln;
end.
На экране появится строка:
Знак курсора во второй строке означает, что программа ожидает ввода. Предположим, пользователь ввел число 34, на экране отобразится еще одна строка:
Если пользователь ошибся и ввел, например, некоторую строку, то программа «выпадет» с ошибкой.
EInOutError ошибка ввода вывода, в данном примере введенная строка не может интерпретироваться как целое число.
Если в программе требуется запросить от пользователя значения нескольких переменных, то можно поступить двумя способами:
Использование нескольких операторов readln |
Использование оператора readln с несколькими параметрами. |
uses SysUtils,Windows; var x:byte; y:real; s:integer; begin SetConsoleCP(1251); SetConsoleOutputCP(1251); writeln('Введите целое число, действительное число, целое число'); readln(x); readln(y); readln(s); writeln('целое число =', x, ' действительное число =',y); writeln(' целое число =',s ); readln; end. |
uses SysUtils,Windows; var x:byte; y:real; s:integer; begin SetConsoleCP(1251); SetConsoleOutputCP(1251); writeln('Введите целое число, действительное число, целое число'); readln(x,y,s); writeln('целое число =', x, ' действительное число =',y); writeln(' целое число =',s ); readln; end. |
Различия |
|
Значения переменных должны вводиться через «Enter». Поскольку операторы выполняются последовательно, то сначала должно быть введено значение для переменной х, нажата клавиша «Enter» и т.д. |
Значения переменных могут вводиться через пробел, знак табуляции или «Enter». При этом важен порядок ввода параметров: первое введенное значение помещается в переменную х, второе в переменную у, третье в переменную s. Если порядок следования параметров будет нарушен, то программа может «выпасть» с ошибкой, т.к. произойдет несовпадение типов данных. |
В Паскале существует понятие формата вывода числа. Для целых чисел предусмотрен следующий формат: writeln(s : 4); - указывается имя переменной, затем ставится знак двоеточия и указывается количество экранных позиций, выделяемых под выводимое число. Даже если выделенных позиций не хватает для вывода числа, то их количество автоматически увеличивается до нужного и число выводится корректно.
Для вывода действительных чисел следует указывать общее количество выводимых цифр и количество цифр после запятой, например: writeln('целое число =', x : 4, ' действительное число =',y:3:2); при этом если у числа количество цифр после запятой меньше, чем указано в формате вывода, оставшиеся позиции будут заполнены нулями, если больше число будет округлено до этого количества знаков.
Для величин целого и вещественного типов данных в Паскале определены стандартные арифметические операции +, -, *, /. Для целых чисел определены еще две операции div и mod. Div это результат целочисленного деления, например, 9 div 4=2, 5 div 3=1. Мod это остаток от деления нацело: 9 mod 4=1, 5 mod 3=2.
Переменной можно присвоить результат вычисления некоторого выражения. При этом тип результата и тип переменной должны быть одинаковыми или совместимыми по присваиванию.
Например, переменной вещественного типа можно присвоить целое значение, при этом в переменную целого типа нельзя поместить вещественное число.
Пример 2.
Пользователь вводит два целых числа, требуется найти их произведение и частное от деления первого числа на второе.
uses SysUtils,Windows;
var z : real;
x, y, mult : integer;
begin
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
writeln('Введите два целых числа');
readln(x,y);
mult:=x*y;
z:=x/y;
writeln('произведение равно ', mult, ' частное равно ', z : 2 : 2);
readln;
end.
В программе объявлены следующие переменные: x, y целочисленные переменные, которые будут содержать значения, введенные пользователем, mult переменная для хранения произведения, она также целого типа, т.к. произведение целых чисел целое число. z переменная, в которой будет храниться частное от деления. Она относится к действительному типу, т.к. при делении одного целого числа на другое, вообще говоря, получается вещественное число.
Первые две строки программы предназначены для организации корректной работы консольного приложения с русским алфавитом (рассмотрены ранее).
writeln('Введите два целых числа'); - на экран выводится текст, указанный в кавычках.
readln(x,y); - происходит считывание значений, введенных с клавиатуры, первое помещается в переменную х, а второе - в переменную у.
mult:=x*y; - переменной mult присваивается результат вычисления выражения.
z:=x/y; - переменной z присваивается результат вычисления выражения.
writeln('произведение равно ', mult, ' частное равно ', z : 2 : 2); - произведение и частное выводятся на экран, с соответствующим текстовым сопровождением.
readln; - задержка экрана.
Пример 3.
Пользователем вводится радиус круга. Определить площадь круга по его радиусу, считать .
uses SysUtils;
var area:real;
radius:integer;
begin
writeln('Введите радиус');
readln(radius);
area:=radius*radius*3.14;
writeln('площадь круга равна ', area:3:2);
readln;
end.
Первый оператор программы выводит на экран информацию для пользователя. Процедура readln(radius); считывает число, введенное пользователем, и размещает его в ячейке памяти с именем radius. Далее переменной area присваивается результат вычисления выражения radius*radius*3.14. Затем значение переменной area выводится на экран с соответствующим текстовым сопровождением. Последний оператор программы выполняет функцию задержки экрана.
Обратите внимание, что в этом примере не использовались процедуры SetConsoleCP(1251); SetConsoleOutputCP(1251); в дальнейших примерах они также будут опускаться для краткости.
В языке программирования Паскаль определен ряд стандартных процедур и функций, некоторые из них рассмотрены в следующих таблицах.
Таблица 1.1
Стандартные функции языка Паскаль
Название функции |
Назначение |
Тип аргумента |
Тип возвращаемого значения |
abs(x) |
модуль аргумента |
целый (вещественный) |
целый (вещественный) |
cos(x) |
косинус аргумента |
целый (вещественный) |
вещественный |
exp(x) |
значение |
целый (вещественный) |
вещественный |
odd(x) |
проверка на четность |
целый |
логический |
sin(x) |
синус аргумента |
целый (вещественный) |
вещественный |
sqr(x) |
квадрат аргумента |
целый (вещественный) |
целый (вещественный) |
sqrt(x) |
квадратный корень из аргумента |
целый (вещественный) |
вещественный |
tan(x) |
тангенс аргумента |
целый (вещественный) |
вещественный |
Таблица 1.2
Стандартные процедуры языка Паскаль
Название процедуры |
Назначение |
Тип аргумента |
inc(x) |
увеличивает значение аргумента на 1 |
целый |
dec(x) |
уменьшает значение аргумента на 1 |
целый |
Стандартные функции могут быть использованы в различных выражениях.
Пример 4.
Вычислить: .
Необходимо объявить три переменные: x, t могут быть целого типа, их значения будут запрашиваться у пользователя, у действительного типа, ее значение будет вычислено в программе.
var y:real;
x,t:integer;
begin
writeln('Введите x и t ');
readln(x,t);
y:=sqrt(x-sin(3*t));
writeln('y=',y:3:2);
readln;
end.
Первый оператор программы выводит на экран информацию для пользователя. Процедура readln(x,t); считывает два числа, введенные пользователем, и размещает их в соответствующих ячейках памяти.
Для вычисления значения у были использованы две стандартные функции sqrt() и sin(). Обратите внимание, что аргументы (параметры) функции записываются в круглых скобках после названия функции. Также нельзя пропускать знаки арифметических операций. Нельзя писать y:=sqrt(x-sin3t); т.к. запись sin3t будет воспринята программой как имя некоторой переменной, а не как функция с параметрами.
Пример 5.
Вычислить: при х=2.
Можно ввести две переменные, одна будет играть роль параметра, другая результата. Обратите внимание, что названия переменных не обязательно должны совпадать с именами в формулировке задания, так в примере переменная, отвечающая за результат, названа z. Как видно из формулировки задания, переменные х и z будут одного типа.
Т.к. в задании сказано вычислить результат выражения при х=2, то значение переменной х не запрашивается у пользователя, а задается в программе (x:=2;). Далее вычисляется результат и выводится на экран.
var z, x:integer;
begin
x:=2;
z:=abs(sqr(x)-7)+1;
writeln('y=', z);
readln;
end.
Пример 6.
Часто при решении задач требуется поменять местами значения переменных. Как это сделать? Зависит от формулировки задания, иногда требуется поменять местами значения без использования дополнительной переменной, но чаще используется другой способ с использованием дополнительной переменной.
Представьте, что у вас есть два стакана, в одном из них находится сок, в другом молоко. Вам нужно поменять местами содержимое этих стаканов. Следует взять третий (пустой) стакан, дальнейшие действия очевидны. Так и с переменными.
var x,y,temp:integer;
begin
{ инициализация переменных}
x:=3; y:=11;
{ изменение значений, temp вспомогательная переменная (пустой стакан)}
temp:=x;
x:=y;
y:=temp;
writeln('x=',x,' y=',y);
readln;
end.
Единственное отличие от аналогии со стаканами состоит в том, что дополнительный стакан после обмена содержимым остается пустым, а в переменной temp после обмена значениями содержится первоначальное значение переменной х. Добавим в программу строчку writeln('temp=', temp); получим результат:
Если в коде программы есть ошибки, то при ее запуске компилятор выводит соответствующие сообщения, а строка, в которой содержится ошибка, выделяется красным цветом.
Наиболее часто встречающиеся ошибки рассмотрены ниже.
Сообщение об ошибке находится в нижней секции окна. Оно начинается со слова Error (в пер. с англ. «ошибка»), далее указывается название файла проекта Project5.dpr и номер строки с ошибкой (в примере 13), причем считаются все строки подряд, включая пустые, начиная с заголовка программы. Далее расшифровывается, в чем состоит ошибка: «Undeclared identifier: z». Это означает, что в программе используется имя переменной (идентификатор), которая не была объявлена в разделе var.
Фраза «Missing operator or semicolon» чаще всего означает, что в предыдущей строке пропущен знак « ; ». Действительно, после оператора х:=2 знак «точка с запятой» отсутствует.
Ошибка «Incompatible types: Integer and Extended» в данном случае означает, что происходит попытка присвоения целочисленной переменной у вещественного значения (а результат вычисления выражения действительно может быть дробным).
Все ошибки, начинающиеся словами «Incompatible types:» означают несовместимость типов. Это может быть присвоение переменной несвойственного ей значения, использование в выражении переменных несовместимых типов (нельзя, например, складывать число и символ) и т.п.
«Error» - это синтаксические ошибки, их найти и исправить наиболее просто. Кроме сообщений об ошибках компилятор выдает предупреждения «Warning» и подсказки «Hint». «Warning» и «Hint» не мешают запуску программы, но они содержат информацию, которая поможет исправить потенциальные, не синтаксические ошибки.
На следующем рисунке показана наиболее часто встречающаяся подсказка, означающая, что некоторая переменная (в примере переменная а) объявлена, но никогда не использовалась в тексте программы.
В следующих «Warning» говорится о том, что переменные x и t используются в программе, при этом они не были проинициализированы. Действительно, в данной программе пропущен либо оператор readln(x,t); либо операторы присваивания (например, x:=2; t:=1;).
а := 5.8;
b := -7.9;
b := а ;
а := b ;
После выполнения лабораторной работы обучаемый должен:
Задания, начинающиеся со слов «С помощью логической переменной проверьте…» следует выполнять без использования операторов ветвления.
Задания №8-№9 групп А и В и Задание №6 группы С следует выполнять с применением оператора выбора, остальные задания нужно решать с помощью условного оператора.
Задание №1
С помощью логической переменной проверьте:
Задание №2
С помощью логической переменной проверьте:
Задание №3
С помощью логической переменной проверьте, что число х принадлежит промежутку:
Задание №4
С помощью логической переменной проверьте, что число х не принадлежит промежутку:
Задание №5
.
.
Задание №6
Задание №7
Задание №8
Задание №9
В обеих задачах принять, что год не является високосным.
В обеих задачах принять, что год не является високосным.
Задание №1
Заданы два (х и у) или три (х, у, с) целых числа, с помощью логической переменной проверьте:
Задание №2
С помощью логической переменной проверьте, что число х принадлежит промежутку:
Задание №3
С помощью логической переменной проверьте, что число х не принадлежит промежутку:
Задание №4
С помощью логической переменной проверьте, что точка с координатами (x,y) принадлежит заданной области.
Геометрические фигуры задаются точкой на плоскости и длинами (-ой)
сторон (-ы) (радиус для круга). Эти параметры задаются пользователем с клавиатуры.
№ |
Фигура 1 |
Фигура 2 |
Выражение |
|
|||
|
|||
|
|||
|
|||
|
|||
|
Задание №5
Задание №6
Решить неравенства:
Задание №7
Задание №8
Задание №9
В обеих задачах принять, что год не является високосным.
В обеих задачах принять, что год не является високосным.
Задание №1
Даны целые числа х и у. С помощью логической переменной проверьте:
Задание №2
С помощью логической переменной проверьте, что точка с координатами (x,y) принадлежит заданной области.
Геометрические фигуры задаются точкой на плоскости и длинами сторон (радиус для круга). Эти параметры задаются пользователем с клавиатуры. При необходимости (например, для треугольников) можно воспользоваться уравнением прямой на плоскости по двум точкам: .
Пример:
Фигура 1 |
Фигура 2 |
Фигура 3 |
Выражение |
№ |
Фигура1 |
Фигура2 |
Фигура 3 |
Выражение |
|
||||
|
или |
|||
|
||||
|
||||
|
или |
|||
|
Задание №3
.
.
Задание №4
Задание №5
Задание №6
Задание выполняется для всех вариантов полностью.
Переменные логического типа boolean могут принимать только два значения true и false истина и ложь. Их объявление также происходит в разделе объявления переменных и имеет вид: var t : boolean;
Начиняя работу с логическим типом, следует вспомнить об операциях отношения, т.е. операциях . Эти операции применимы к переменным многих типов данных, при этом результат их применения относится к логическому типу. Например, результат выражения a*b>c (где a, b и c вещественные переменные) будет истинным при наборе значений a=2.3, b=7, c=3.5 и ложным при наборе чисел a=2.3, b=7, c=20.5.
Поскольку результат таких выражений будет логическим, то его можно присвоить переменной логического типа: t:=( a*b>c); при различных значениях переменных a, b и c переменная t будет принимать значения true или false.
Значение переменных логического типа можно вывести на экран с помощью оператора writeln().
Пример 1.
Пользователь вводит два числа, проверить, равны ли эти числа.
var t:boolean;
a,b:integer;
begin
writeln('Введите два числа');
readln(a,b);
t:=(a=b);
writeln('Числа равны? ', t);
readln;
end.
В программе объявлены две переменные целого типа и одна логического. Значения целочисленных переменных вводятся с клавиатуры, а логической переменной присваивается результат вычисления выражения a=b, результат будет истинным, если два числа равны и ложным в противном случае. Далее значение переменной t выводится на экран с соответствующим текстовым сопровождением.
Результат работы программы:
К переменным логического типа можно применять следующие операции: and, or, not, xor. Пусть А и В переменные типа boolean. Далее приведена таблица истинности для логических операций. Для удобства вместо значения false в ней используется 0, а вместо true 1.
А |
В |
А and В |
А or В |
А xor В |
not А |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
Пример 2.
Проверить, что число х, введенное пользователем положительно и четно. Для проверки одновременного выполнения двух (и более) условий применяется логическая операция AND.
var t1,t2,t:boolean;
x:integer;
begin
writeln('Введите число');
readln(x);
t1:=(x>0);
t2:=(x mod 2 =0);
t:=t1 and t2;
writeln('Число четно и положительно ',t);
readln;
end.
В программе объявлены три переменные логического типа, переменной t1 присваивается результат вычисления выражения (x>0), это означает, что t1 примет значение «истина», если х положительно, и «ложь» в противном случае. Переменная t2 примет значение «истина», если х четно, т.е. остаток от деления числа х на 2 равен 0, и «ложь» если х нечетно. Следующий оператор программы - t:=t1 and t2; переменная t будет истинной, если обе переменные t1 и t2 истинны одновременно (т.е. одновременно выполняются условия положительности и четности) и ложной в противном случае.
В данной программе переменные t1 и t2 являются вспомогательными и без них можно обойтись.
var t:boolean;
x:integer;
begin
writeln('Введите число');
readln(x);
t:=(x>0) and (x mod 2 =0);
writeln('Число четно и положительно ',t);
readln;
end.
Приведенные программы эквивалентны. При выполнении лабораторных работ, в случае если логическое выражение не слишком сложное, рекомендуется работать в соответствии со вторым вариантом программы.
Результат работы программы:
Обратите внимание, что при записи составных условий, например, (x>0) and (x mod 2 =0) оба условия должны быть заключены в скобки. Записи t:=(x>0 and x mod 2 =0); или t:=x>0 and x mod 2 =0; вызовут ошибку:
Пример 3.
С помощью логической переменной проверьте, что остаток от деления хотя бы одной цифры двузначного числа на 3 равен 1.
Из формулировки задачи ясно, что логическая переменная должна принимать значение истина, если
Ложь если обе цифры условию не отвечают. Такой результат дает применение логической операции or.
var t:boolean;
x,a1,a10:integer;
begin
writeln('Введите число');
readln(x);
a1:=x mod 10;
a10:=x div 10;
t:=(a1 mod 3 =1) or (a10 mod 3 =1);
writeln(' Остаток от деления хотя бы одной цифры на 3 равен 1 ', t);
readln;
end.
В программе использовались две дополнительные переменные a1 и a10, a1 количество единиц двузначного числа, a10 количество десятков двузначного числа. Если в условии задачи встречаются слова «…хотя бы одна…» - это означает, что нужно использовать операцию or. Переменная t примет значение истина, если результат хотя бы одного выражения (a1 mod 3 =1) или (a10 mod 3 =1) будет истинным.
Пример 4.
С помощью логической переменной проверить, принадлежит ли число х, введенное пользователем, промежутку [-3, 10).
Т.е. число должно быть не меньше левой границы и не превышать правой границы промежутка (одновременное выполнение двух условий).
var t:boolean;
x:integer;
begin
writeln('Введите число');
readln(x);
t:=(x>=-3) and (x<10);
writeln('Число х= ', x ,' принадлежит промежутку [-3,10)? ', t);
readln;
end.
Обратите внимание, что понятию «объединение» в математике соответствует логическая операция OR, а понятию «пересечение» - операция AND.
Пример 5.
С помощью логической переменной определить, принадлежит ли точка с координатами (х, у) заданной области.
Во-первых, нужно запросить координаты точки у пользователя. Далее нужно проверить попадает ли точка в эту область. Выделенная область представляет собой пересечение трех областей:
Чтобы точка попала в верхнюю полуплоскость ее координата у должна быть положительна, в правую полуплоскость положительна координата х. Чтобы попасть во внутрь окружности координаты точки должны удовлетворять условию: , где R радиус окружности, - координаты центра окружности. Пересечение областей находится с помощью логической операции AND.
var x,y : real;
res : boolean;
begin
writeln(Введите координаты точки на плоскости);
readln(x, y);
res:=(0 < x) and (0 < y) and ((sqr(x) + sqr(y)) < 1);
writeln(Точка принадлежит области? , res);
readln;
end.
В задачах часто возникают ситуации, когда при выполнении некоторого условия должен быть реализован один набор действий, а если условие не выполняется - другой. Например, вспомним определение модуля числа: , если число неотрицательно, то модуль числа равен самому числу, в противном случае модуль равен числу, взятому с противоположным знаком. В этой задаче, если условие истинно должны быть выполнены одни действия, если ложно другие. Говорят, что процесс вычислений разветвляется на два направления. Для решения таких задач используется условный оператор.
Синтаксис условного оператора:
if <выражение> then <оператор_1> else <оператор_2>;
Результат вычисления выражения, которое следует за ключевым словом if, должен быть логического типа. Т.е. <выражение> представляет собой условие, которое может быть как простым, например, x>0 или t=true, так и составным с использованием логических операций.
Если перевести ключевые слова условного оператора на русский язык, то получится следующее: если (if) выражение истинно, то (then) выполняется один набор операторов, иначе (else) выполняется другой набор операторов.
Обратите внимание:
Пример 6.
Найти модуль числа, введенного пользователем.
var x,modul:real;
begin
writeln('Введите число х');
readln(x);
if (x>=0) then modul:=x else modul:=-x;
writeln('|x|=', modul:0:2);
readln;
end.
Пример 7.
Пользователь вводит два числа а и b, если первое число больше второго, найти их разность (а - b) и вывести ее на экран, в противном случае - их произведение (а * b) и вывести на экран.
var a,b, s1,s2:real;
begin
writeln('Введите числа а и b ');
readln(a,b);
if (a>b) then begin
s1:=a-b;
writeln('Разность чисел равна ', s1:0:2);
end
else begin
s2:=a*b;
writeln('Произведение чисел равно ', s2:0:2);
end;
readln;
end.
Пользователь вводит два числа. Затем в условном операторе проверяется условие: первое число больше второго? В случае когда условие истинно (т.е. по ветви then ), вычисляется разность чисел и присваивается переменной s1, на экран выводится значение переменной s1 и текстовое сопровождение. Если условие ложно (второе число больше первого или числа равны), то высчитывается произведение чисел, присваивается переменной s2, значение переменной s2 выводится на экран. Обратите внимание, при таком решении задачи по ветви then и по ветви else должно выполняться по два оператора, а, значит, их следует заключить в операторные скобки, если операторные скобки не будут расставлены, то компилятор выдаст ошибку:
Операторные скобки расставляются следующим образом:
Рассмотренный пример можно было выполнить без использования дополнительных переменных s1 и s2 и операторных скобок, переменные были введены искусственно, чтобы продемонстрировать работу с операторными скобками. Ниже приведен код программы для решения той же задачи, но без использования дополнительных переменных. Обратите внимание, что параметрами процедуры writeln могут быть не только переменные и строковые константы, но и выражения различной сложности.
var a,b:real;
begin
writeln('Введите числа а и b ');
readln(a,b);
if (a>b) then writeln('Разность чисел равна ', a-b:0:2)
else writeln('Произведение чисел равно ', a*b:0:2);
readln;
end.
Пример 8.
В примере №5 требовалось определить, принадлежит ли точка с координатами (х, у) заданной области (с помощью логической переменной).
Рассмотрим то же задание, но решать его будем не только с помощью логических переменной, но и условного оператора.
var x,y : real;
t1,t2 : boolean;
begin
writeln('Введите координаты точки на плоскости');
readln(x, y);
t1:=(0 < x) and (0 < y); { принадлежность точки первой четверти}
t2:=(sqr(x) + sqr(y)) < 1; { принадлежность точки окружности}
if (t1=true) and (t2=true) { если точка принадлежит пересечению областей}
then writeln('Точка принадлежит области')
else writeln(' Точка не принадлежит области ');
readln;
end.
Запись if (t1=true) and (t2=true) … эквивалентна записи if t1 and t2 …
Рассмотрим пример: пользователь вводит число, если число положительно, требуется вывести на экран куб этого числа. В данном примере, при выполнении условия (число положительно) следует выполнить некоторые действия (вычислить куб числа и вывести его на экран), что нужно делать в случае невыполнения условия, в задании не сказано. Для решения задач такого типа применяется краткая форма условного оператора, в которой отсутствует ветвь else.
if <выражение> then <оператор_1>;
По ветви then краткой формы условного оператора может быть выполнен только один оператор, если требуется записать несколько операторов, то их следует заключить в операторные скобки.
var x,cub:integer;
begin
writeln('Введите число ');
readln(x);
if (x>0) then begin
cub:=x*sqr(x);
writeln('x*x*x= ',cub);
end;
readln;
end.
Если операторные скобки не поставить, то по ветви then выполнится только один оператор, а именно cub:=x*sqr(x); а значение переменной cub будет выводиться на экран в любом случае.
var x,cub:integer;
begin
writeln('Введите число ');
readln(x);
if (x>0) then
cub:=x*sqr(x);
writeln('x*x*x= ',cub);
readln;
end.
При этом компилятор выдает предупреждение о том, что переменная cub может быть не проинициализирована, такая ситуация возникнет, если пользователь введет отрицательное число или 0. В этом случае компилятор (в зависимости от настроек) может проинициализировать переменную cub нулем или другим произвольным значением, и при вводе пользователем, например, числа -3 на экран может быть выведена запись «х*х*х=1».
Пример 9.
Заданы три целых числа, необходимо возвести в квадрат отрицательные числа.
В задании требуется возвести в квадрат числа удовлетворяющие условию, т.е. изменения должны произойти с самими переменными. Если значение переменной отрицательно, то переменная должна принять новое значение, равное квадрату предыдущего значения (a:=sqr(a);).
var a,b,c:integer;
begin
write('a='); readln(a);
write('b='); readln(b);
write('c='); readln(c);
if (a<0) then begin
a:=sqr(a);
writeln('a*a=',a);
end;
if (b<0) then begin
b:=sqr(b);
writeln('b*b=',b);
end;
if (c<0) then begin
c:=sqr(c);
writeln('c*c=',c);
end;
readln;
end.
Если в задании требуется только вывести на экран квадраты отрицательных чисел, то код программы упростится:
var a,b,c:integer;
begin
write('a='); readln(a);
write('b='); readln(b);
write('c='); readln(c);
if (a<0) then writeln('a*a=',a*a);
if (b<0) then writeln('b*b=',b*b);
if (c<0) then writeln('c*c=',c*c);
readln;
end.
С точки зрения пользователя никаких изменений не произойдет, при запуске обеих программ результат будет один и тот же.
Но в первом варианте значения переменных a, b и c меняются, если переменные удовлетворяют условию, а во втором варианте остаются неизменными.
Пример 10.
Заданы три целых числа, следует подсчитать количество четных чисел.
var a,b,c,count:integer;
begin
write('a='); readln(a);
write('b='); readln(b);
write('c='); readln(c);
count:=0;
if (a mod 2=0) then inc(count);
if (b mod 2=0) then inc(count);
if (c mod 2=0) then inc(count);
writeln('Количество четных чисел равно ', count);
readln;
end.
В переменной count будет храниться количество четных чисел. Перед проверкой введенных чисел на четность, переменную count следует проинициализировать: count:=0;. Затем каждое из трех чисел проверяется на четность, если число является таковым значение переменной count увеличивается на единицу с помощью процедуры inc(). После проверки всех чисел, значение count выводится на экран.
Пример 11.
Заданы три целых числа, проверить, есть ли среди них четные числа.
Данную задачу можно решить аналогично предыдущей, следует только проверить в конце значение переменной count, если оно положительно, значит, такие числа есть, если равно нулю значит, четных чисел нет. Но обычно задачи, в которых требуется ответить на вопрос «есть ли…?», «является ли…?» решаются с помощью переменных логического типа. Эти переменные до начала проверки должны быть явно проинициализированы (например, t:=false;), затем в процессе проверки могут изменить свое значение.
var a,b,c:integer;
t:boolean;
begin
write('a='); readln(a);
write('b='); readln(b);
write('c='); readln(c);
t:=false;
if (a mod 2=0) then t:=true;
if (b mod 2=0) then t:=true;
if (c mod 2=0) then t:=true;
if t then writeln('есть четные числа ') else writeln('нет четных чисел');
readln;
end.
При разветвлении процесса вычислений на множество направлений используется оператор выбора.
Синтаксис оператора выбора имеет вид:
case <выражение> of
<значение_1> : <оператор_1>;
<значение_2> : <оператор_2>;
…
<значение_n> : <оператор_n>;
else <оператор>;
end;
<выражение> - это может быть результат вычисления некоторого выражения или имя переменной, но обязательно порядкового типа (порядковыми считаются типы данных, значения которых можно занумеровать: все целочисленные, символьный, логический, тип-диапазон и перечисляемые типы).
<значение_1>…<значение_n> - некоторые константы, возможные значения переменной или результаты вычисления выражения.
<оператор_1>; -оператор, который необходимо выполнить, если результат <выражения> равен <значению_1> и т.д.
По ветви else прописывается оператор, выполняемый, когда результат <выражения> не совпадает ни с одним из возможных значений. Ветвь else может отсутствовать. Перед словом else знак «;» может присутствовать, в отличие от условного оператора, это не является ошибкой.
Оператор выбора обязательно оканчивается ключевым словом end;
По каждой ветви оператора выбора может быть выполнен только один оператор, если необходимо записать несколько операторов, их следует заключать в операторные скобки.
Пример 12.
Пользователь вводит номер дня недели, следует вывести на название этого дня (1 понедельник, 3 среда и т.п.). Чтобы решить эту задачу с помощью условного оператора, потребуется семикратное использование сокращенной формы оператора if.
var x:byte;
begin
writeln('Введите номер дня недели');
readln(x);
if (x=1) then writeln('Понедельник');
if (x=2) then writeln('Вторник');
if (x=3) then writeln('Среда');
if (x=4) then writeln('Четверг');
if (x=5) then writeln('Пятница');
if (x=6) then writeln('Суббота');
if (x=7) then writeln('Воскресенье');
readln;
end.
Программа, выполненная таким образом, является достаточно громоздкой. При использовании оператора выбора код программы станет более простым.
var x:byte;
begin
writeln('Введите номер дня недели');
readln(x);
case x of
1:writeln('Понедельник');
2:writeln('Вторник');
3:writeln('Среда');
4:writeln('Четверг');
5:writeln('Пятница');
6:writeln('Суббота');
7:writeln('Воскресенье');
else writeln('нет дня недели с таким номером');
end;
readln;
end.
Если пользователь введет число 3, на экран выведется текст «среда» и т.п.
Пример 13.
Пользователь вводит два числа и знак математической операции (+, -, *, /), на экран должен быть выведен результат взаимодействия чисел в зависимости от операции (если пользователь вводит «+», то на экране должна отобразиться сумма чисел).
var a,b,s1:integer;
s2:real;
ch:char;
begin
writeln('Введите два числа ');
readln(a,b);
writeln(' Введите знак арифметической операции');
readln(ch);
case ch of
'+': begin
s1:=a+b;
writeln('a+b= ',s1);
end;
'-': begin
s1:=a-b;
writeln('a-b= ',s1);
end;
'*': begin
s1:=a*b;
writeln('a*b= ',s1);
end;
'/': begin
s2:=a/b;
writeln('a/b= ',s2:0:2);
end;
else writeln('это не знак арифметической операции ');
end;
readln;
end.
После выполнения лабораторной работы обучаемый должен:
Задания №1-№3 из Группы А, №1-№4 Группы В, №1-№4 Группы С должны быть выполнены с использованием цикла с параметром. Остальные задания должны быть выполнены в двух вариантах: с использованием циклов с предусловием и постусловием.
Для получения требуемой степени числа функции power() и exp() не использовать.
Задания групп В и С следует решать без использования вложенных циклов.
Задание №1.
Задание №2.
Найти:
Задание №3.
Задание №4.
Задание №5.
Пользователь вводит натуральное число и целые числа . Определить:
Задание №6.
Дано натуральное число. Определить:
Задание №1.
Задание №2.
Пользователем вводится некоторое натуральное число n, вычислить:
Задание №3.
Вводится N произвольных чисел от 0 до 255. Определить для соответствующих им по кодам символов:
Задание №4.
Пользователь вводит N произвольных чисел, определить:
Задание №5.
Дано натуральное число. Определить:
Задание №6.
Задание №7.
Задание №1.
Написать программу для вычисления выражений. Операцию возведения в степень и вложенные циклы не использовать!
Задание №2.
Написать программу для вычисления выражений. Операцию возведения в степень и вложенные циклы не использовать!
Задание №3.
Вводится N произвольных чисел от 0 до 255. Определить для соответствующих им по кодам символов:
Задание №4.
Пользователь вводит N произвольных чисел, определить:
Задание №5.
Задание №6.
Задание №7.
Пользователь вводит произвольные целые числа. Определить:
Задание №8.
Пользователь вводит произвольные символы. Определить:
В языках программирования для организации повторяющихся действий используются операторы циклов. Наиболее простым является оператор цикла с параметром (for).
for <параметр_цикла>:=<нач_значение> to <конеч_значение> do <оператор>;
Параметром цикла может быть любая переменная порядкового типа, имя параметра цикла определяет пользователь, но по сложившейся традиции целочисленные параметры цикла обозначают буквами «i» и «j».
Обратите внимание:
Существует еще один вариант записи цикла for.
for <параметр_цикла>:=<нач_значение> downto <конеч_значение> do <оператор>;
Обратите внимание:
остальные требования аналогичны рассмотренной выше форме цикла с параметром.
В методических материалах к предыдущей лабораторной работе был рассмотрен пример.
Пример 1.
Заданы три целых числа, следует подсчитать количество четных чисел.
var a,b,c,count:integer;
begin
write('a='); readln(a);
write('b='); readln(b);
write('c='); readln(c);
count:=0;
if (a mod 2=0) then inc(count);
if (b mod 2=0) then inc(count);
if (c mod 2=0) then inc(count);
writeln('Количество четных чисел равно ', count);
readln;
end.
Обратите внимание, что для всех трех чисел выполняются аналогичные действия:
С помощью цикла for рассмотренную программу можно переписать следующим образом:
var a,i,count:integer;
begin
count:=0;
for i:=1 to 3 do
begin
writeln(' Введите ', i ,'-e число ');
readln(a);
if (a mod 2=0) then inc(count);
end;
writeln('Количество четных чисел равно ', count);
readln;
end.
Поскольку после проверки числа на четность, его значение больше нигде не используется, то можно объявить только одну переменную, в которую будет помещаться значение, считанное с клавиатуры на каждой итерации цикла (в примере, это переменная а). Переменная count отвечает за количество четных чисел, а переменная i является параметром цикла for.
Запись for i:=1 to 3 do … означает следующее: для всех значений переменной i, изменяющейся от 1 до 3 выполнить…
Результат работы программы:
Пример 2.
Напечатать таблицу перевода 10, 20, 30 … 150 см. в метры.
Можно поступить двумя способами, первый: перебрать все значения от 10 до 150 и все кратные 10 значения перевести в метры. В таком варианте тело цикла будет состоять только из одного оператора (if).
var i:integer;
begin
for i:=10 to 150 do
if (i mod 10=0) then writeln(i, ' см = ',i/100 :0:2,' м');
readln;
end.
При таком способе решения цикл for будет совершать 141 итерацию (150-10+1=141), хотя в действительности нужно рассмотреть только 15 значений.
Второй способ: в цикле можно перебрать значения от 1 до 15, а нужные значения сантиметров получить умножением итерационной переменной на 10, а соответствующие значения в метрах делением сантиметров на 100. В примере введены две вспомогательные переменные sm и m, но можно обойтись и без них.
var sm,i:integer;
m:real;
begin
for i:=1 to 15 do
begin
sm:=i*10;
m:=sm/100;
writeln(sm, ' см = ',m:0:2,' м');
end;
readln;
end.
Результат работы программы:
Пример 3.
Вывести на экран все двузначные числа, кратные 17.
Диапазон двузначных чисел: 10..99. В цикле следует перебрать все числа из этого диапазона, проверить каждое число на кратность 17, если число кратно 17 вывести его на экран.
var i:integer;
begin
write('Двузначные числа, кратные 17: ');
for i:=10 to 99 do
if (i mod 17 =0) then write(i,' ');
readln;
end.
Пример 4.
Найти среднее арифметическое всех четных чисел из диапазона -7 ..10.
Среднее арифметическое равно отношению суммы чисел, отвечающих условию, к их количеству.
var sum,count, i:integer;
sr_ar:real;
begin
count:=0; sum:=0;
for i:=-7 to 10 do
if (i mod 2=0) then begin
sum:=sum+i;
count:=count+1; // inc(count);
end;
sr_ar:=sum/count;
writeln('среднее арифметическое равно ',sr_ar:0:2);
readln;
end.
В программе введены две дополнительные переменные sum, для накопления суммы четных чисел и count, для подсчета их количества. Эти переменные должны быть проинициализированы нулями до начала цикла.
Затем в цикле перебираются все числа из указанного диапазона, если удовлетворяет условию задачи (т.е. i mod 2=0), то выполняются два действия:
После завершения цикла переменной sr_ar присваивается значение, равное среднему арифметическому четных чисел из указанного диапазона (sr_ar:=sum/count;). Этот оператор нельзя записывать в теле цикла, т.к. до полного завершения цикла значение переменных sum и count не отвечают условиям задачи.
Пример 5.
Пользователь вводит N действительных чисел, вывести на экран положительные числа.
var N,i:integer;
x:real;
begin
writeln('Введите количество чисел');
readln(N);
for i:=1 to N do
begin
write('Введите ', i, '-e число ');
readln(x);
if (x>0) then writeln(x:0:2, ' положительно');
end;
readln;
end.
Число N количество чисел, вводимых пользователем. Это число может быть запрошено у пользователя или задано в программе, например, в виде константы. Если N не будет определено, то не будет известно конечное значение итерационной переменной, т.е. сколько раз будет выполнено тело цикла (относится только к данной задаче).
В теле цикла выполняются операторы:
Результат работы программы:
Пример 6.
Напечатать числа от 1 до 10 в обратном порядке.
var i:integer;
begin
for i:=10 downto 1 do
write(i, ' ');
readln;
end.
Результат работы программы:
В теле цикла могут выполняться произвольные операторы. Если в теле цикла выполняется еще один цикл, то такие циклы называются вложенными.
Пример 7.
Напечатать таблицу умножения.
var i,j:1..9;
begin
for i:=1 to 9 do
begin
for j:=1 to 9 do
write(i*j:4);
writeln;
end;
readln;
end.
Обратите внимание, что в качестве типа для итерационных переменных выбран тип диапазон 1..9, т.к. исходя из условий задачи, эти переменные не могут принимать другие значения.
Результат работы программы:
Цикл, параметром которого является переменная i, часто называют «цикл по i», а цикл for j:=1 to 9 do… соответственно «цикл по j».
В цикле по i выполняются два оператора: цикл по j и writeln без параметров, последний нужен для перехода на следующую строку. В теле цикла for j:=1 to 9 do… выполняется только один оператор write(i*j:4); который выводит число на экран, выделяя под него 4 позиции (этим обуславливается одинаковое расстояние между столбцами). Оператор write не переводит курсор на следующую строку, поэтому все числа, равные i*j печатаются в одну строку.
Добавим в программу еще один оператор writeln('Начало ', i, '-й итерации , i=', i ); он будет выполняться на каждой итерации цикла по i и сообщать о номере итерации.
var i,j:1..9;
begin
for i:=1 to 9 do
begin
writeln('Начало ', i, '-й итерации , i=', i );
for j:=1 to 9 do
write(i*j:4);
writeln;
end;
readln;
end.
Результат работы программы:
Становится понятным порядок выполнения операторов во вложенных циклах:
Если возникли трудности с пониманием работы вложенных циклов, рекомендуется рассмотреть еще один пример.
Пример 8.
Распечатать на экране номера месяцев и дней.
Упростим задачу, будем считать, что в каждом месяце 30 дней. Во внешнем цикле (по i) будут перебираться номера месяцев, а во внутреннем номера дней.
var i,j:byte;
begin
for i:=1 to 12 do
begin
writeln('i=',i);
for j:=1 to 30 do
write(j, ' ');
writeln;
end;
readln;
end.
Результат работы программы:
Цикл с параметром используется в случае, когда количество итераций заранее известно, при этом параметр и границы цикла могут быть величинами только порядкового типа. В языке программирования Паскаль существуют еще два оператора цикла, они называются операторами цикла с условиями. Они применяются, если количество итераций цикла заранее неизвестно и в других ситуациях.
Рассмотрим оператор цикла while <условие> do <оператор>;. while и do зарезервированные слова, <условие> - некоторое выражение, результат которого относится к типу boolean, <оператор> - либо один произвольный оператор, либо набор операторов, заключенных в операторные скобки. Читается: пока (while) условие истинно, выполнять (do) тело цикла (<оператор>). Как только <условие> станет ложным, выполнение тела цикла завершится.
Поскольку условие проверяется до выполнения тела цикла, while называется циклом с предусловием.
Обратите внимание, что:
Пример 9.
Задана последовательность натуральных чисел 1 5 9 13 17… и вещественное число n>1, подсчитать сумму членов последовательности меньших n.
Рассмотрим решение этой задачи с помощью оператора цикла с предусловием. Поскольку n вещественное число, оно не может выступать в качестве границы цикла с параметром (for i:=1 to n do…).
var n:real;
k,sum:integer;
begin
writeln('Введите число');
readln(n);
k:=1; sum:=0;
while (k<n) do
begin
sum:=sum+k;
k:=k+4;
end;
writeln('Сумма чисел равна ',sum);
readln;
end.
Сумма чисел будет накапливаться в переменной sum, а последовательность чисел перебираться с помощью переменной i. Пользователь вводит вещественное число n, переменным k и sum присваиваются начальные значения. Т.к. первый член последовательности равен 1, переменной k присваивается это значение. Инициализация переменных, участвующих в цикле до начала цикла обязательна.
Выполнение цикла начинается с поверки условия, если условие ложно тело цикла не выполнится ни разу. В данном примере оператором, который обращает условие на входе в цикл в ложное, является оператор k:=k+4;
Результат работы программы:
Пример 10.
Подсчитать количество слагаемых, при котором заданная сумма не будет превышать числа М>1, заданного пользователем.
При решении данного примера должен использоваться оператор цикла, при этом количество итераций заранее неизвестно, следовательно, нужно использовать цикл с условием.
В переменной sum будет накапливаться сумма ряда, переменная count отвечает за количество слагаемых, М число, введенное пользователем.
var M,sum:real;
count:integer;
begin
writeln('Введите число');
readln(M);
count:=0; sum:=0;
while (sum<=M) do
begin
inc(count);
sum:=sum+1/count;
end;
writeln('Количество слагаемых равно ', count-1);
readln;
end.
При таком решении выполняется лишняя итерация, т.к. на последней итерации значение переменной sum превысит значение переменной М и количество слагаемых окажется больше на 1. Эту ситуацию можно исправить, если вывести на экран количество слагаемых, равное count-1. Либо можно не допускать переполнения переменной sum. Это можно сделать изменив условие на входе в цикл:
var M,sum:real;
count:integer;
begin
writeln('Введите число');
readln(M);
count:=0; sum:=0;
while (sum+1/(count+1)<=M) do
begin
inc(count);
sum:=sum+1/count;
end;
writeln('Количество слагаемых равно ',count, ' Cумма равна=', sum:0:10);
readln;
end.
Здесь проверяется условие (sum+1/(count+1)<=M), т.е. значение суммы на текущем шаге вместе со следующим слагаемым не должно превышать значение переменной М. Тогда на экран должно быть выведено не count-1, а count. Значение переменной sum выводится для демонстрации того, что оно действительно не превышает числа М.
В данном примере оператором, который обращает условие на входе в цикл в ложное, является оператор sum:=sum+1/count;.
Результат работы программы:
Пример 11.
Дано натуральное число. Вывести на экран все цифры числа в обратном порядке.
В задании не сказано, сколько цифр содержится в числе, поэтому следует использовать цикл с условием. Пусть N число, введенное пользователем, k вспомогательная переменная. Принцип решения данной задачи заключается в следующем: на каждой итерации цикла будет распечатываться последняя цифра числа, т.е. младший разряд, а затем она будет отбрасываться, т.е. число на каждом шаге будет уменьшаться в 10 раз.
var N,k:word;
begin
writeln('Введите натуральное число');
readln(N);
while (N<>0) do
begin
k:=N mod 10;
write(k);
N:=N div 10;
end;
readln;
end.
В данном примере оператором, который обращает условие на входе в цикл в ложное, является оператор N:=N div 10;.
Имеет вид repeat <оператор> until <условие>;
Читается: повторять (repeat) тело цикла (<оператор>) до тех пор, пока (until) условие не станет истинным.
Особенности цикла с постусловием:
Поскольку тело оператора цикла с постусловием выполняется хотя бы один раз, этот оператор удобно использовать в организации диалога с пользователем. До этого момента все программы были написаны таким образом, что при проверке корректности работы программы на нескольких наборах входных данных ее приходилось неоднократно запускать. После изучения операторов цикла можно организовать работу программу таким образом, что пользователь сможет вводить сколько угодно наборов входных данных, а из программы выйти после совершения определенного действия.
Пример 12.
Перепишем программу из примера №11 с помощью оператора цикла с постусловием.
var N,k:word;
begin
writeln('Введите число');
readln(N);
repeat
k:=N mod 10;
write(k);
N:=N div 10;
until (N=0);
readln;
end.
Пример 13.
Проверить, является ли число, введенное пользователем, положительным, отрицательным или равным нулю.
Пусть программа запрашивает у пользователя число и выдает результат, пока пользователь не введет латинскую букву «n».
var x:integer;
ch:char;
begin
repeat
writeln('Введите число');
readln(x);
if (x>0)
then writeln('Число положительно')
else if (x<0)
then writeln('Число отрицательно')
else writeln('Число равно 0');
writeln('Продолжить: y/n (yes/no) ');
readln(ch);
until (ch='n') or (ch='N');
writeln('Завершение программы');
readln;
end.
На каждой итерации цикла у пользователя запрашивается число, проверяется знак числа, после этого пользователю задается вопрос: хочет ли он продолжить ввод и проверку чисел, и предлагается ввести латинскую букву «n» для завершения работы программы. Если пользователю требуется продолжить ввод чисел, он может нажать любую клавишу. После ввода буквы «n» произойдет выход из цикла. В программе предусмотрено, что пользователь может ввести заглавную букву «N».
Результат работы программы:
Цикл с параметром всегда можно заменить циклом с предусловием.
Пример 14.
Пользователь вводит два натуральных числа: и . Напечатать квадраты всех чисел из диапазона … .
Решение задачи с помощью цикла с параметром имеет вид:
var i,n1,n2:byte;
begin
writeln('Введите два числа n1<n2');
readln(n1,n2);
for i:=n1 to n2 do
writeln(i,'^2=',sqr(i));
readln;
end.
Решение задачи с помощью цикла с предусловием имеет вид:
var i,n1,n2:byte;
begin
writeln('Введите два числа n1<n2');
readln(n1,n2);
i:=n1;
while (i<=n2)do
begin
writeln(i,'^2=',sqr(i));
inc(i);
end;
readln;
end.
Обратите внимание на различия:
Выход из цикла произойдет, когда значение переменной i превысит значение n2.
При решении такой задачи с использованием цикла с постусловием необходимо использование дополнительного условного оператора. Если пользователь ошибся, и число n2 оказалось меньше числа n1, то тело цикла while, также как и тело цикла for не выполнится ни разу, т.к. условие на входе в цикл окажется ложным. Но тело цикла с постусловием выполняется хотя бы один раз при любых условиях, поэтому необходимо до цикла использовать дополнительный условный оператор, чтобы в такой ситуации не допустить выполнения тела цикла.
.
.
После выполнения лабораторной работы обучаемый должен:
Задания №3 и №4 для группы С следует решать с применением операторов цикла с условием.
Задания №5 - №7 для группы С следует решать без использования дополнительного массива.
В заданиях №6 и №7 для группы С под удалением элемента массива следует понимать:
Под вставкой числа а в массив после k-ro элемента следует понимать:
Задание №1
Дан массив целых чисел. Выяснить:
Задание №2
Задание №3
Дан массив вещественных чисел. Вывести на экран новое состояние массива, в котором:
Задание №4
Задание выполняется для всех вариантов полностью.
Дан массив вещественных чисел. Найти:
Задание №5
Задание выполняется для всех вариантов полностью.
Дан массив вещественных чисел. Переставить местами:
Задание №6
Задание №7
Задание №8
Дан двумерный массив. Определить:
Задание №9
Задание №10
Задание №1
Дан массив вещественных чисел, требуется:
Задание №2
Задание №3
Задание №4
Задание выполняется для всех вариантов полностью.
Дан массив целых чисел. Поменять местами:
Задание №5
Дан двумерный массив целых чисел. Требуется:
Задание №6
Дан двумерный массив целых чисел. Определить:
Задание №7
Задание №8
Задание №9
Задание №1
Задание №2
Задание №3
Задание №4
При решении следует предусмотреть возможность отсутствия в массиве искомых элементов.
Задание №5
a[n+1], a[n+2], . . .,a[2n], a[n], a[n-1], . . ., a[1].
a[2n], a[2n-1], . . .,a[n+1], a[1], a[2], . . ., a[n].
Задание №6
Удалить из массива (новый массив распечатать):
Задание №7
Задание №8
Задание №9
Задание №10
Задание №11
Задание №12
Заполнить двумерный массив следующим образом:
12 |
13 |
36 |
… |
109 |
11 |
14 |
… |
… |
110 |
… |
… |
… |
… |
… |
2 |
… |
26 |
… |
… |
1 |
24 |
25 |
… |
120 |
111 |
112 |
… |
120 |
… |
… |
… |
… |
30 |
… |
22 |
21 |
11 |
12 |
… |
20 |
10 |
… |
2 |
1 |
120 |
… |
25 |
24 |
1 |
… |
… |
26 |
… |
2 |
… |
… |
… |
… |
… |
110 |
… |
… |
14 |
… |
109 |
… |
36 |
13 |
12 |
120 |
… |
112 |
111 |
… |
… |
… |
… |
20 |
… |
12 |
11 |
10 |
… |
2 |
1 |
109 |
… |
36 |
13 |
12 |
110 |
… |
… |
14 |
11 |
… |
… |
… |
… |
… |
… |
… |
26 |
… |
2 |
120 |
… |
25 |
24 |
1 |
1 |
24 |
25 |
… |
120 |
2 |
… |
26 |
… |
… |
… |
… |
… |
… |
… |
… |
14 |
… |
… |
110 |
12 |
13 |
36 |
… |
109 |
Переменная типа одномерный массив объявляется следующим образом:
var <имя_переменной> : array [<тип_индекса>] of <тип_элементов>;
Например,
var а: array [1..5] of real;
c, d: array [0..12] of char;
Обращение к элементу массива осуществляется через указание имени массива и порядкового номера элемента.
Например, пусть задан массив целых чисел с именем MyArray:
var MyArray : array [1..10] of integer;
При объявлении переменной типа одномерный массив в квадратных скобках указывается его размер. Данный массив будет состоять из 10 элементов, причем первый элемент имеет индекс «1», а последний - «10». В языке программирования Паскаль нумерация элементов в статических массивах обычно начинается с 1, но возможны и другие варианты.
Чтобы обратиться к элементу массива, нужно указать его имя и индекс элемента в квадратных скобках, если вы хотите обратиться ко второму элементу массива MyArray, то должны записать MyArray[2], к пятому - MyArray[5] и т.д.
Индекс массива не обязательно должен быть числовой константой, он может быть переменной или результатом вычисления выражения (здесь нужно следить, чтобы результат вычисления выражения совпадал по типу с типом индекса массива и при этом не выходил за указанные границы, в рассматриваемом примере это диапазон 1..10). Например:
Элементам массива можно присваивать произвольные значения (соответствующие указанному типу элементов), они также могут участвовать в выражениях различной сложности. В данном примере все элементы массива MyArray имеют тип integer, следовательно, для них допустимы все операции, определенные для целых чисел:
var MyArray:array [1..10] of integer;
x:byte;
s:real;
begin
…
MyArray[1]:=7;
MyArray[3]:=x mod 5;
s:=(MyArray[1]+MyArray[10])/2;
if (MyArray[5]=0) then writeln(MyArray[5]);
…
end.
После объявления переменной MyArray (var MyArray:array [1..10] of integer;) происходит выделение памяти под десять элементов типа integer. После этого, как и при объявлении обычных переменных, в этих ячейках памяти находятся неопределенные значения. В некоторых случаях (для локальных переменных) это могут быть произвольные числа вида: 1245080, 2167001 или нули. Поэтому прежде чем начать работу с массивом необходимо заполнить массив или, говоря иначе, проинициализировать его элементы.
Элементам массива можно присвоить некоторые значения непосредственно при написании программы:
…
MyArray[1]:=7;
MyArray[3]:=x mod 5;
…
или запросить значения элементов у пользователя:
…
readln(MyArray[1]);
readln(MyArray[2]);
…
В примере массив состоит всего из 10 элементов, поэтому можно организовать заполнение массива следующим образом:
var MyArray:array [1..10] of integer; x,i:byte; s:real; begin … MyArray[1]:=2; MyArray[2]:=3; MyArray[3]:=4; MyArray[4]:=5; MyArray[5]:=6; MyArray[6]:=7; MyArray[7]:=8; MyArray[8]:=9; MyArray[9]:=10; MyArray[10]:=11; … end. |
или |
var MyArray:array [1..10] of integer; x,i:byte; s:real; begin … readln(MyArray[1]); readln(MyArray[2]); readln(MyArray[3]); readln(MyArray[4]); readln(MyArray[5]); readln(MyArray[6]); readln(MyArray[7]); readln(MyArray[8]); readln(MyArray[9]); readln(MyArray[10]); … end. |
Такой способ не очень удобен даже когда массив состоит из небольшого количества элементов, при этом теряется смысл использования массива, т.к. можно было просто объявить 10 переменных типа integer и работать с ними. А что делать, если количество элементов массива равно 10000?
Чаще всего работу с элементами массива осуществляют через использование циклов. Т.к. количество элементов массива заранее известно, для многих задач подходит цикл с параметром. Например, программу заполнения массива можно переписать следующим образом:
var MyArray:array [1..10] of integer; x,i:byte; s:real; begin … for i:=1 to 10 do MyArray[i]:=i+1; … end. |
или |
var MyArray:array [1..10] of integer; x,i:byte; s:real; begin … for i:=1 to 10 do readln(MyArray[i]); … end. |
Такая запись более компактна, а при изменении размера массива нужно поменять только значения границ для параметра цикла.
В некоторых случаях для заполнения массива используют генератор псевдослучайных чисел.
…
Randomize;
for i:=1 to 10 do
MyArray[i]:=random(20);
…
Число 20 в записи random(20) означает, что генератор будет выдавать числа из диапазона [0, 20). Вместо 20 можно указать любое целое положительное число. Оператор Randomize; выполняет обновление генератора, если его убрать, то при каждом запуске программы массив будет заполняться одним и тем же набором значений.
После заполнения массива с помощью генератора псевдослучайных чисел рекомендуется вывести массив на экран, иначе пользователь не сможет оценить правильность решения задачи на полученном наборе чисел.
Осуществляется с использованием оператора цикла и операторов write() или writeln() в теле цикла.
…
for i:=1 to 10 do
write(MyArray[i],' ');
…
Результатом выполнения этого блока кода будет вывод на экран элементов массива MyArray в одну строку, элементы будут разделены пробелами.
Замечание.
В примерах, рассмотренных выше, массив задавался следующим образом:
var MyArray:array [1..10] of integer;
т.е. верхняя граница индекса представлена некоторым числом (здесь 10). Такой способ не очень удобен, т.к. если возникнет необходимость изменения размера массива, то придется вносить изменения не только в объявление массива, но и во все операторы цикла (for i:=1 to 10 do …), предназначенные для обработки массива. Поэтому при работе со статическими массивами рекомендуется до их объявления массива задать константу, которая будет определять его длину:
const n=10;
var MyArray: array [1..n] of integer;
В этом случае операторы цикла для обработки массива будут иметь вид:
for i:=1 to n do …
и для изменения размера массива в программе достаточно поменять значение константы n.
Пример 1.
Проверить, есть ли в массиве элемент равный 10.
Решение задач, в которых есть слова «есть ли», «является ли», «равен ли» и т.д., обычно начинается с введения переменной типа boolean, поскольку в задаче нужно дать ответ вида «да/нет». В данной задаче этой переменной до начала проверки всех элементов присваивается значение «ложь», т.к. в массиве может не оказаться элементов, отвечающих поставленному условию. Затем каждый элемент массива проверяется на соответствие условию, если он отвечает условию, то логической переменной присваивается значение «истина».
const n=10;
var MyArray:array [1.. n] of integer;
i:byte;
t:boolean;
begin
Randomize;
for i:=1 to n do { заполнение массива случайным образом}
MyArray[i]:=random(20);
for i:=1 to n do
write(MyArray[i],' '); {вывод массива на экран}
t:=false;
for i:=1 to n do {проверка элементов на соответствие условию}
if (MyArray[i]=10) then t:=true;
writeln('есть элементы, равные 10? ', t);
readln;
end.
Обратите внимание, что при решении задачи используется краткая форма условного оператора. Использование полной формы условного оператора (if (MyArray[i]=10) then t:=true else t:=false;) в задачах такого типа приводит к ошибке, т.к. выполнение этого оператора на каждой итерации «затирает» результат проверки элемента на предыдущем шаге. Пусть имеется набор элементов 1 2 3 4 10 2 3 4 1 5, тогда на шаге №5 переменная t примет значение true, а уже на следующем шаге она станет равной false. Результатом работы программы будет вывод на экран строки: «есть элементы, равные 10? false», хотя в массиве есть элемент, отвечающий условию.
В решение этой задачи можно внести некоторые изменения. Пусть был сгенерирован следующий набор чисел: 10 2 3 4 11 2 3 4 1 5. Т.е. уже на первом шаге переменная t приняла значение true и ответ на вопрос задачи уже получен, но элементы массива будут проверяться до последнего, т.е. происходит выполнение лишних операций. Хорошо было бы организовать решение таким образом, чтобы после нахождения элемента, отвечающего условию, проверка элементов прекращалась.
var MyArray:array [1..10] of integer;
i:byte;
t:boolean;
begin
Randomize;
for i:=1 to 10
MyArray[i]:=random(20);
for i:=1 to 10 do
write(MyArray[i],' ');
t:=false; i:=1;
while (not t) and (i<=10) do
begin
if (MyArray[i]=10) then t:=true;
inc(i);
end;
writeln('есть элементы, равные 10? ', t);
readln;
end.
Пример 2.
Найти сумму элементов массива.
const n=5;
var MyArray:array [1..n] of integer;
i:byte;
sum:integer;
begin
Randomize;
for i:=1 to n do { инициализация элементов и вывод на экран}
begin
MyArray[i]:=random(20);
write(MyArray[i],' ');
end;
sum:=0;
for i:=1 to n do { нахождение суммы элементов массива}
sum:=sum+MyArray[i];
writeln('сумма равна ', sum);
readln;
end.
В программе объявляется переменная, предназначенная для вычисления суммы sum. Перед суммированием всех элементов, переменная sum должна быть проинициализирована. Затем в цикле последовательно перебираются все элементы массива и добавляются к предыдущему значению переменной sum.
Обратите внимание, что инициализация элементов массива и вывод их на экран помещены в тело одного оператора цикла (на одной итерации цикла определяется значение элемента и производится вывод его на экран).
Пример 3.
Найти количество элементов массива, кратных 5, их произведение и вывести на экран номера этих элементов.
Решение этой задачи отличается от предыдущей тем, что нужно обработать не все элементы массива, а только те, которые отвечают некоторому условию (в примере - кратные 5). При этом требуется с этими элементами выполнить не одно действие, а сразу несколько:
const n=5;
var MyArray:array [1..n] of integer;
i,count:byte;
mult:integer;
begin
Randomize;
for i:=1 to n do
begin
MyArray[i]:=random(20);
write(MyArray[i],' ');
end;
writeln;
mult:=1; count:=0;
for i:=1 to n do
if (MyArray[i] mod 5=0)
then begin
mult:=mult*MyArray[i];
inc(count);
writeln(i);
end;
if (count>0) then writeln('произведение равно ', mult, ' количество равно ',count )
else writeln( 'в массиве нет таких элементов');
readln;
end.
Для вычисления произведения вводится переменная mult, которой присваивается начальное значение, равное единице, а для вычисления количества вводится переменная count=0. Затем на каждой итерации цикла происходит проверка, отвечает ли элемент заданному условию (if (MyArray[i] mod 5=0)…). В случае выполнения условия:
Т.к. для элементов отвечающих условию, нужно выполнить несколько действий, тело условного оператора заключается в операторные скобки. После проверки всех элементов организуется вывод результатов вычислений на экран, при этом проверяется, были ли найдены в массиве элементы, отвечающие условию (if (count>0)…). Если такие элементы есть в массиве, на экран выводятся результаты, в противном случае сообщение о том, что таких элементов нет.
Пример 4.
Все элементы одномерного массива с четными номерами заменить нулями.
Это означает, что второй, четвертый, шестой и т.д. элементы массива (независимо от их значения) должны стать нулями. В цикле перебираются все элементы массива, если номер элемента, т.е. значение итерационной переменной, четно, то значение элемента изменяется на 0. После обработки всего массива организуется вывод на экран новых значений элементов.
const n=10;
var MyArray:array [1..n] of integer;
i:byte;
begin
Randomize;
for i:=1 to n do
begin
MyArray[i]:=random(20);
write(MyArray[i],' ');
end;
writeln;
{ изменение значений элементов}
for i:=1 to n do
if (i mod 2=0) then MyArray[i]:=0;
{ вывод массива после внесения изменений}
for i:=1 to n do
write(MyArray[i],' ');
readln;
end.
Можно изменить условие задачи следующим образом: все четные элементы массива заменить нулями. Это означает, что нужно приравнять нулю те элементы, значение которых делится на 2 (а не значение номера). Т.е. в программу нужно внести следующие изменения:
…
{ изменение значений элементов}
for i:=1 to n do
if (MyArray[i] mod 2=0) then MyArray[i]:=0;
…
Пример 5.
Поменять местами первый и р-й элементы массива.
Такая постановка задачи подразумевает ввиду, что значение р должен ввести пользователь (readln(p);), а в программе должна быть организована проверка, что р не выходит за границы массива ( if (p>=1) and (p<=n) then…). Если пользователь вводит верное число, происходит обмен значениями между р-м и первым элементами массива (по принципу обмена значений двух обычных переменных с использованием дополнительной переменной) и вывод массива на экран. В противном случае на экран должна быть выведена информация, что введенное число выходит за границы массива.
const n=10;
var MyArray:array [1..n] of integer;
i,p:byte;
temp:integer;
begin
Randomize;
for i:=1 to n do
begin
MyArray[i]:=random(20);
write(MyArray[i],' ');
end;
writeln;
writeln('Введите номер элемента');
readln(p);
if (p>=1) and (p<=n)
then begin
{ обмен значениями}
temp:= MyArray[1];
MyArray[1]:=MyArray[p];
MyArray[p]:=temp;
{ вывод массива на экран}
for i:=1 to n do
write(MyArray[i],' ');
end
else writeln('элемента с таким номером в массиве нет');
readln;
end.
Пример 6.
Поиск максимального элемента массива.
Для решения этой задачи вводится дополнительная переменная (назовем ее max), в которой будет храниться значение максимального элемента массива. Ее тип должен совпадать с типом элементов массива. Алгоритм поиска: до начала просмотра массива переменной max присваивается значение первого элемента массива. Затем в цикле перебираются все элементы массива и сравниваются с max, если встретится элемент, значение которого больше max, то переменной max присваивается значение этого элемента. Таким образом, после перебора всех элементов переменная max действительно содержит значение, равное максимальному элементу массива.
const n=5;
var MyArray: array [1..n] of real;
i:integer;
max:real;
begin
{ заполнение массива и вывод на экран}
Randomize;
for i:=1 to n do
begin
MyArray[i]:=random(20)/5;
write(MyArray[i]:0:2,' ');
end;
writeln;
{ поиск максимального элемента}
max:=MyArray[1];
for i:=2 to n do
if (MyArray[i]>max) then max:=MyArray[i];
writeln('max=',max:0:2);
readln;
end.
Если в задаче требуется найти максимальный элемент и его номер, то в код программы нужно внести изменения:
const n=5;
var MyArray: array [1..n] of real;
i,nmax:integer;
max:real;
begin
Randomize;
for i:=1 to n do
begin
MyArray[i]:=random(20)/5;
write(MyArray[i]:0:2,' ');
end;
writeln;
{поиск максимального элемента и его номера}
max:=MyArray[1];
nmax:=1;
for i:=2 to n do
if (MyArray[i]>max) then begin
max:=MyArray[i];
nmax:=i;
end;
writeln('max=',max:0:2, ' nmax=',nmax);
readln;
end.
Пример 7.
Сортировка массива методом «пузырька».
Принцип этого метода сортировки заключается в следующем: берется элемент массива (на первом этапе первый, на втором второй и т.п.) и последовательно сравнивается со всеми остальными элементами массива, если встречается элемент меньший по значению, то происходит перестановка элементов. Таким образом, за первый этап самый «легкий» элемент оказывается в начале массива, т.е. становится его первым элементом. На втором этапе уже второй элемент сравнивается со всеми элементами справа от него, если встречается меньший элемент, происходит перестановка. Получаем, что минимальный элемент уже из части массива с индексами 2..n, становится в ее начало, т.е. теперь имеет индекс 2 и т.д.
Рассмотрим принцип действия на наборе элементов: 19 6 11 5 3.
Этап 1 (первая итерация цикла по i).
Таким образом, самый «легкий» элемент оказался в начале массива.
Этап 2 (вторая итерация цикла по i). Массив имеет вид: 3 19 11 6 5.
На втором месте оказался наименьший по значению элемент из оставшейся части массива 3 19 11 6 5 .
Этап 3 (третья итерация цикла по i). Те же действия выполняются для части массива 3 5 19 11 6. Получаем массив: 3 5 6 11 19. Он оказался отсортированным, но проверка не закончена.
Этап 4. (i=4). Аналогичные действия для оставшейся части массива: 3 5 6 11 19. На данном этапе для рассматриваемого набора значений перестановок не происходит.
Обратите внимание, что каждый этап реализован для оставшейся части массива, т.е. стоящие на своем месте элементы уже не рассматриваются. Это достигается за счет того, что внутренний цикл начинается не с 1, а с i+1 ( for j:=i+1 to n do…).
const n=5;
var MyArray: array [1..n] of real;
i,j:integer;
temp:real;
begin
Randomize;
for i:=1 to n do
begin
MyArray[i]:=random(100)/5;
write(MyArray[i]:0:2,' ');
end;
writeln;
{сортировка}
for i:=1 to n-1 do
for j:=i+1 to n do
if MyArray[i] > MyArray[j]
then begin
temp:=MyArray[i];
MyArray[i]:=MyArray[j];
MyArray[j]:=temp;
end;
writeln('отсортированный массив:');
for i:=1 to n do
write(MyArray[i]:0:2,' ');
readln;
end.
Пример 8.
Переставить элементы массива в обратном порядке.
На первой итерации цикла переставляются элементы с номерами 1 и n, на второй итерации 2 и n-1, на третьей: 3 и n-2 и т.д. Таким образом, можно определить зависимость номеров элементов на каждой итерации меняются местами элементы с номерами i и n-i+1. Обратите внимание на то, что максимальное значение итерационной переменной i равно n div 2 (а не n). Если бы цикл выполнился n раз, то в итоге получился исходный порядок элементов: 1 3 0 2 9.
const n=5;
var MyArray: array [1..n] of real;
i:integer;
temp:real;
begin
Randomize;
for i:=1 to n do
begin
MyArray[i]:=random(20);
write(MyArray[i]:0:2,' ');
end;
writeln;
{ перестановка элементов}
for i:=1 to n div 2 do
begin
temp:=MyArray[i];
MyArray[i]:=MyArray[n-i+1];
MyArray[n-i+1]:=temp;
end;
writeln('элементы массива в обратном порядке');
for i:=1 to n do
write(MyArray[i]:0:2,' ');
readln;
end.
Пример 9.
Найти произведение трех первых четных элементов массива.
Решить эту задачу можно следующим образом: ввести переменную count, отвечающую за количество четных элементов, перебрать все элементы массива, при появлении четного элемента значение этой переменной увеличивать на 1, при этом произведение накапливать только в том случае, пока count<=3. После просмотра всех элементов массива произведение следует выводить на экран только тогда, когда count>=3, т.е. в массиве нашлось три или более четных элементов, в противном случае на экран нужно вывести информацию, что такого количества четных элементов в массиве нет.
const n=10;
var MyArray: array [1..n] of integer;
i,count:byte;
mult:integer;
begin
Randomize;
for i:=1 to n do
begin
MyArray[i]:=random(10);
write(MyArray[i],' ');
end;
writeln;
{нахождение произведения}
count:=0; mult:=1;
for i:=1 to n do
if (MyArray[i] mod 2=0)
then begin
inc(count);
if (count<=3) then mult:=mult*MyArray[i];
end;
if (count>=3) then writeln('mult=',mult) else writeln('в массиве менее трех четных элементов');
readln;
end.
Такой способ решения задачи обладает рядом недостатков. Например, в ситуации, когда в начале массива стоят три четных элемента, проверка остальных элементов является излишней. Поэтому было бы рациональнее организовать выход из цикла в том случае, когда найдено нужное количество четных элементов.
…
{ нахождение произведения}
i:=1;
count:=0; mult:=1;
while (count<3) and (i<=n) do
begin
if (MyArray[i] mod 2=0)
then begin
inc(count);
mult:=mult*MyArray[i];
end;
inc(i);
end;
if (count=3) then writeln('mult=',mult) else writeln('в массиве менее трех четных элементов');
…
Обратите внимание на второе условие в цикле while (count<3) and (i<=n) do… Первое условие очевидно: как только встретятся три четных элемента, так произойдет выход из цикла. Второе условие предусматривает ситуацию, когда в массиве менее трех четных элементов. Без этого условия цикл продолжал бы выполняться и после i=10,
что привело бы к выходу за границы массива, т.е. к ошибке.
Происходит аналогично объявлению одномерного массива, отличие заключается только в указании типа индекса:
var <имя_переменной>:array[<тип_индекса_1>,<тип_индекса_2>] of <тип_элементов>;
Например,
var а: array [1..5, 1..4] of real;
c, d: array [0..12, 0..2] of integer;
Обращение к элементу массива осуществляется через указание имени массива, номеров строки и столбца, на пересечении которых находится элемент.
Например, пусть задан двумерный массив целых чисел с именем MyArray:
const m=3; n=4;
var MyArray:array [1..m, 1..n] of integer;
В квадратных скобках указывается количество строк в массиве 1..m и количество столбцов 1..n. Данный массив будет состоять из 12 элементов (3*4=12).
Чтобы обратиться к элементу массива, нужно указать его имя затем, в квадратных скобках (через запятую) номер строки и номер столбца, на пересечении которых он находится. Например, MyArray[1,1] первый элемент массива (находящийся в верхнем левом углу), MyArray[m,n] последний элемент массива (находящийся в нижнем правом углу), MyArray[1,3] элемент, находящийся на пересечении первой строки и третьего столбца.
Индексы элементов двумерного массива, как и в случае одномерного, не обязательно должны быть числовыми константами. Они могут быть переменными или результатами вычисления выражений. Например,
MyArray[2,4], MyArray[k,p], MyArray[k div 2 +1, p-1]…
(где k и p целочисленные переменные).
При таком обращении к элементам двумерного массива нужно следить, чтобы результат вычисления выражений совпадал по типу с типом индексов массива и при этом не выходил за указанные границы.
Для заполнения двумерного массива нужно использовать два вложенных оператора цикла.
Заполнение массива значениями, вводимыми пользователем.
…
for i:=1 to m do
for j:=1 to n do
begin
write('MyArray[', i ,',', j ,']=');
readln(MyArray[i,j]);
end;
…
Первый оператор цикла (с итерационной переменной i) перебирает номера строк массива, а второй оператор номера столбцов.
На рисунке видно, что на каждой итерации цикла с переменной i, цикл по переменной j, отвечающий за перебор номеров столбцов, выполняется 4 раза, а переменная j пробегает значения от 1 до 4:
Заполнения массива с помощью генератора случайных чисел.
…
randomize;
for i:=1 to m do
for j:=1 to n do
MyArray[i,j]:=random(30);
…
Можно реализовать с помощью следующего блока кода.
…
for i:=1 to m do
begin
for j:=1 to n do
write(MyArray[i,j]:4);
writeln;
end;
…
Обратите внимание, что после вывода на экран элементов каждой строки ( for j:=1 to n do write(MyArray[i,j]:4); ), используется оператор writeln без параметров. Это нужно для того, чтобы каждая строка массива печаталась с новой строки.
В операторе write(MyArray[i,j]:4); часть «:4» означает, что для вывода данной переменной отводится 4 экранные позиции. На рисунке ниже приведен пример использования вместо write(MyArray[i,j]:4); оператора write(MyArray[i,j], ' ');
Т.к. количество цифр в элементах массива может быть различно, то вывод матрицы в виде ровных столбцов не получится, поэтому рекомендуется использовать вывод с выделением позиций экрана.
Для задач на обработку двумерного массива характерно требование провести исследование не всех элементов массива, а какой-то его части (главной диагонали, столбца, строки и т.п.). Либо провести обработку каждой строки или столбца массива.
Пример 10.
В какой строке массива количество нулевых элементов больше: в первой или последней?
Номера строк в этой задаче известны первая (№1) и последняя (№ m), т.е. они являются константами и о время работы программы не изменятся. Нужно просмотреть элементы каждой из этих строк и посчитать количество нулевых элементов в них. Т.е. изменяться в программе будут только номера столбцов.
const m=3; n=4;
var MyArray:array [1..m, 1..n] of integer;
i,j,k1,km:byte;
begin
{задание элементов массива и вывод на экран}
randomize;
for i:=1 to m do
begin
for j:=1 to n do
begin
MyArray[i,j]:=random(2);
write(MyArray[i,j]:3);
end;
writeln;
end;
{ подсчет количества нулевых элементов}
k1:=0; km:=0;
for j:=1 to n do
begin
if (MyArray[1,j]=0) then inc(k1);
if (MyArray[m,j]=0) then inc(km);
end;
{ сравнение количества нулевых элементов}
if (k1>km) then writeln('в первой строке больше')
else if (k1<km) then writeln('в последней строке больше')
else writeln('поровну');
readln;
end.
Аналогичное задание: «В каком столбце массива количество нулевых элементов больше: в первом или последнем?».
При решении этого задания нам известны номера столбцов: первый (№1) и последний (№ n). Эти номера фиксированы. В программе будут изменяться только номера строк.
…
{ подсчет количества нулевых элементов}
k1:=0; km:=0;
for i:=1 to m do
begin
if (MyArray[i,1]=0) then inc(k1);
if (MyArray[i,n]=0) then inc(km);
end;
…
Пример 11.
Поменять местами элементы двумерного массива с номерами [k1,p1] и [k2,p2].
Подразумевается, что номера этих элементов введет пользователь, а в программе будет реализована проверка того, что эти номера не выходят за границы массива. Обмен происходит по принципу обмена значений двух обычных переменных с использованием дополнительной переменной.
const m=3; n=4;
var MyArray:array [1..m, 1..n] of integer;
i,j,k1,k2,p1,p2:byte;
t1,t2:boolean;
temp:integer;
begin
{ инициализация элементов массива и вывод их на экран}
randomize;
for i:=1 to m do
begin
for j:=1 to n do
begin
MyArray[i,j]:=random(20);
write(MyArray[i,j]:3);
end;
writeln;
end;
{обмен значениями}
writeln('введите номер первого элемента');
readln(k1,p1);
writeln('введите номер второго элемента');
readln(k2,p2);
{ проверка, что номера введенных элементов не выходят за границы массива}
t1:=(k1>0) and (k1<=m) and (p1>0) and (p1<=n);
t2:=(k2>0) and (k2<=m)and (p2>0) and (p2<=n);
if (t1 and t2)
then begin
{ перестановка}
temp:=MyArray[k1,p1];
MyArray[k1,p1]:=MyArray[k2,p2];
MyArray[k2,p2]:=temp;
end;
{ вывод массива после внесения изменений}
for i:=1 to m do
begin
for j:=1 to n do
write(MyArray[i,j]:3);
writeln;
end;
readln;
end.
Пример 12.
Найти сумму элементов главной диагонали.
Понятие главной и побочной диагонали применимо только к квадратным матрицам.
Элементы главной диагонали массива характеризуются тем, что у них первый и второй индекс одинаковы: MyArray[1,1], MyArray[2,2], …, MyArray[n,n].
В задании требуется найти сумму всех таких элементов.
const n=4;
var MyArray:array [1..n, 1..n] of integer;
sum,i,j:integer;
begin
{ заполнение массива и вывод на экран}
randomize;
for i:=1 to n do
begin
for j:=1 to n do
begin
MyArray[i,j]:=random(20);
write(MyArray[i,j]:3);
end;
writeln;
end;
{ вычисление суммы элементов главной диагонали}
sum:=0;
for i:=1 to n do
for j:=1 to n do
if (i=j) then sum:=sum+MyArray[i,j];
writeln('sum=',sum);
readln;
end.
Таким образом просматриваются все элементы массива, если окажется, что у элемента одинаковые индексы (if ( i=j) …), то этот элемент добавляется к сумме (…then sum:=sum+MyArray[i,j];).
Такой способ работы с диагональными элементами не рационален, т.к. приходится просматривать и проверять на соответствие условию все элементы массива, программа в этом случае выполняет множество лишних операций. Можно не перебирать весь массив, а рассмотреть только сами диагональные элементы, пользуясь равенством их индексов.
…
{ вычисление суммы элементов главной диагонали}
sum:=0;
for i:=1 to n do
sum:=sum+MyArray[i,i];
…
Аналогичное задание: найти сумму элементов побочной диагонали.
Элементы побочной диагонали массива: MyArray[1,n], MyArray[2,n-1], …, MyArray[n,1]. Т.е. их индексы связаны следующей зависимостью: j = n-i+1. Поэтому для нахождения их суммы также достаточно одного оператора цикла (а не двух вложенных).
…
{ вычисление суммы элементов побочной диагонали}
sum:=0;
for i:=1 to n do
sum:=sum+MyArray[i, n-i+1];
…
Пример 13.
Определить количество нулевых элементов в каждой строке двумерного массива.
Для задач такого типа обычно вводится одна дополнительная переменная (а не по одной для каждой строки), т.к. в задаче не требуется дальнейшей обработки полученных значений. В примере эта переменная названа count. Обратите внимание, что значение этой переменной обнуляется в начале каждой итерации цикла по переменной i.
Выше обсуждалось, что при таком порядке операторов цикла и индексов элементов, цикл по i перебирает номера строк массива, а по j - номера столбцов.
const m=3; n=4;
var MyArray:array [1..m, 1..n] of integer;
i,j,count:byte;
begin
{заполнение массива и вывод на экран}
randomize;
for i:=1 to m do
begin
for j:=1 to n do
begin
MyArray[i,j]:=random(20);
write(MyArray[i,j]:5);
end;
writeln;
end;
{подсчет количества нулевых элементов в каждой строке}
for i:=1 to m do
begin
count:=0;
for j:=1 to n do
if (MyArray[i,j]=0) then inc(count);
writeln('кол-во нулевых элементов в ', i , '-ой строке=', count);
end;
readln;
end.
Результат работы программы:
Аналогичное задание: определить количество нулевых элементов в каждом столбце двумерного массива.
Решение этой задачи отличается от предыдущей тем, что элементы массива следует перебирать не по строкам, а по столбцам. Этого можно достичь, поменяв местами операторы цикла:
…
{количество нулевых элементов в каждом столбце}
for j:=1 to n do
begin
count:=0;
for i:=1 to m do
if (MyArray[i,j]=0) then inc(count);
writeln('кол-во нулевых элементов в ' ,j, '-ом столбце=', count);
end;
…
Теперь внешний цикл (по переменной j ) перебирает номера столбцов, а внутренний номера строк, т.е. обход массива осуществляется по столбцам.
Пример 14.
Поменять местами первую и р-ю строки (число р вводит пользователь).
Переставить две строки массива означает, что нужно поменять местами соответственно все элементы этих строк. Перестановку двух элементов массива можно выполнить с использованием вспомогательной переменной, тип которой совпадает с типом элементов массива. Номера строк фиксированы это 1 и р. Для перестановки элементов строк используется цикл по i, (чтобы перебрать все номера столбцов). На первой итерации меняются местами элементы MyArray[1,1] и MyArray[р,1], на второй - MyArray[1,2] и MyArray[р,2], на третьей - MyArray[1,3] и MyArray[р,3], на четвертой - MyArray[1,4] и MyArray[р,4].
const m=3;n=4;
var MyArray:array [1..m, 1..n] of integer;
i,j,p:byte;
temp:integer;
begin
randomize;
for i:=1 to m do
begin
for j:=1 to n do
begin
MyArray[i,j]:=random(20);
write(MyArray[i,j]:5);
end;
writeln;
end;
{ перестановка строк}
writeln('введите номер строки');
readln(p);
if (p>=1) and (p<=m)
then for i:=1 to n do
begin
temp:=MyArray[1,i];
MyArray[1,i]:=MyArray[p,i];
MyArray[p,i]:=temp;
end
else writeln(' ошибка ввода ');
{вывод измененного массива на экран}
for i:=1 to m do
begin
for j:=1 to n do write(MyArray[i,j]:5);
writeln;
end;
readln;
end.
Аналогичное задание: переставить местами первый и р-й столбец (число р вводит пользователь). В этом задании фиксированы номера столбцов, а номера строк, т.е. первый из индексов элементов массива, должен изменяться. На первой итерации меняются местами элементы MyArray[1,1] и MyArray[1,р], на второй - MyArray[2,1] и MyArray[2,р], на третьей - MyArray[3,1] и MyArray[3,p].
…
{ перестановка столбцов}
writeln('введите номер столбца');
readln(p);
if (p>1) and (p<=n)
then for i:=1 to m do
begin
temp:=MyArray[i,1];
MyArray[i,1]:=MyArray[i,p];
MyArray[i,p]:=temp;
end
else writeln(' ошибка ввода ');
…
После выполнения лабораторной работы обучаемый должен:
Задание №1
Задание №2
Задание №3
Задание №4
Путем копирования подстрок получить:
Задание №5
Путем вставок и удаления символов исправить ошибки:
Задание №1
Путем копирования подстрок получить:
Задание №2
Задание №3
Задание №4
Задание №5
Задание №1
Задание №2
Задание №3
Задание №4
Задание №5
Переменная строкового типа задается следующим образом:
var <имя_переменной>: string;
Например, var MyString: string;
После объявления строковой переменной под нее выделяется определенный блок памяти, но содержимое этого блока неясно. Для дальнейшей работы с переменной MyString ей нужно присвоить некоторое значение. Оно может быть определено через:
MyString:='Моя первая строка';
Для ввода и вывода строковых переменных используют операторы readln и writeln.
Обращение к элементу строки осуществляется также как и к элементу одномерного массива через указание имени строки и порядкового номера элемента. Элемент строки совместим с типом char, т.е. элемент строки это символ.
Переменная строкового типа схожа по структуре с одномерным массивом символов, отличается же от массива набором стандартных процедур и функций, определенных для работы со строками.
В языке программирования Паскаль элементу строки можно присвоить некоторое значение.
Пример 1.
…
MyString[1]:=a;
MyString[k-1]:=s;
…
Также элемент строки может участвовать в выражениях:
…
if ( MyString[3]=w ) then …
…
и т.п.
Длина строки.
Функция length() возвращает длину строки, т.е. количество символов в строке.
Обратите внимание, даже в случае, когда в программе указывается максимальный размер строки, функция length() вернет значение реальной длины строки. Так в примере на экран выведется число 3, а не 80.
var MyString:string[80];
n:byte;
begin
MyString:='123';
n:= length(MyString);
writeln(n);
readln;
end.
Чаще всего функция length() используется при решении задач, в которых нужно перебрать все символы строки (for i:=1 to length(MyString) do...).
Конкатенация строк.
Функция Concat() «склеивает» строки, передаваемые ей в качестве параметров. Она возвращает строку, которая является результатом объединения строк-параметров. Например, после выполнения следующего кода переменная MyString примет значение «гололед».
var MyString,s1,s2:string;
begin
s1:='гол';
s2:='лед';
MyString:=Concat(s1, 'о', s2);
writeln(MyString);
readln;
end.
Этой функцией пользуются достаточно редко, т.к. тот же результат обеспечивает применение обычной операции «+». Т.е. строку кода MyString:=Concat(s1, 'о', s2); можно заменить на MyString:=s1+ 'о'+ s2; результат будет тем же.
Остальные процедуры и функции представлены в таблице ниже. Более подробно они рассмотрены в примерах №7-№10.
Таблица 5.1
Процедуры и функции для работы со строками
Название процедуры / функции |
Выполняемое действие |
Copy(s, start, len) |
Функция. Возвращает подстроку длиной len, начинающуюся с позиции start строки s. Параметры len и start должны быть целого типа. |
Pos(subs, s) |
Функция. Ищет вхождение подстроки subs в строку s и возвращает номер первого вхождения subs в s или нуль, если subs не содержится в s. |
Delete(s, start, len) |
Процедура. Удаляет из строки s, начиная с позиции start, подстроку длиной len. |
Insert(subs, s, start) |
Процедура. Вставляет в строку s подстроку subs, начиная с позиции start. |
Str(x, s) |
Процедура. Преобразует числовое значение х в строку s, при этом для x может быть задан формат, как в процедурах вывода write и writeln, например Str(x:6:2, s). |
Val (s, x, errcode) |
Процедура. Преобразует строку s в значение числовой переменной х, при этом строка s должна содержать символьное представление числа. В случае успешного преобразования переменная errcode равна нулю. Если же обнаружена ошибка, то errcode будет содержать номер позиции первого ошибочного символа, а значение х не определено. |
Часто в задачах требуется обработать некоторый текст, состоящий из нескольких строк. Возникает вопрос: где хранить эти строки и как к ним обращаться. Для удобного хранения и обработки используют массивы, элементами которых являются строки.
Строковый массив объявляется также как и обычные массивы:
var MyArray:array [1..20] of string;
Обращение к элементу строкового массива аналогично обращение к элементу обычного массива, при этом не следует забывать, что элементами являются строки, для которых определено множество стандартных процедур и функций.
Работа с массивом строк будет продемонстрирована в примере № 9.
Пример 2.
Запросить у пользователя его имя и поприветствовать пользователя с использованием его имени.
var MyString: string;
begin
writeln('Введите Ваше имя');
readln(MyString);
writeln(' Здравствуйте, ',MyString, '!');
readln;
end.
Обратите внимание, что параметром первого оператора является строковая константа ('Введите Ваше имя').
Пример 3.
Пользователь вводит два имени, проверить, есть ли среди них имя Татьяна.
var MyString1,MyString2: string;
begin
writeln('Введите первое имя');
readln(MyString1);
writeln(' Введите второе имя ');
readln(MyString2);
if (MyString1= 'Татьяна') or (MyString2= 'Татьяна') then
writeln('есть') else writeln('нет') ;
readln;
end.
Пример 4.
Пользователь вводит некоторую строку. Определить есть ли в ней буква «Д».
Данное задание можно решить двумя способами. Во-первых, можно перебрать с помощью оператора цикла все символы строки и сравнить каждый символ с буквой «Д».
var MyString: string;
i:integer;
t:boolean;
begin
writeln('Введите строку');
readln(MyString);
t:=false;
for i:=1 to length(MyString) do
if (MyString[i]='Д') then t:=true;
writeln(t);
readln;
end.
Второй способ заключается в использовании стандартной функции, определенной для переменных и констант строкового типа. Функция Pos проверяет, содержится ли некоторая подстрока в рассматриваемой строке, если да функция возвращает номер первого вхождения, иначе 0. Т.е. если буква «Д» содержится в строке, функция Pos вернет число большее 0, в противном случае - вернет 0.
var MyString: string;
i:integer;
begin
writeln('Введите строку');
readln(MyString);
if (Pos( 'Д', MyString)>0) then writeln('да') else writeln('нет');
readln;
end.
Пример 5.
Пользователь вводит некоторую строку. Заменить все символы с номерами 5, 10, 15, 20 …на вопросительные знаки.
Последовательно перебираем номера от 1 до length(MyString), если встречается номер, кратный пяти, то элемент строки с этим номером заменяется на «?».
var MyString: string;
i:integer;
begin
writeln('Введите строку');
readln(MyString);
for i:=1 to length(MyString) do
if (i mod 5=0) then MyString[i]:='?';
writeln(MyString);
readln;
end.
Пример 6.
Задана строка «Моя программа». Скопировать в другую строковую переменную часть исходной строки, начиная с 5 символа по 13.
Сделать копию части строки можно с помощью функции Copy. Первым параметром этой функции является имя строки, часть которой нужно скопировать, второй параметр номер символа строки, с которого начинается копирование, третий количество символов, которое необходимо скопировать. Т.к. в примере требовалось скопировать часть строки с 5-го по 13-й символ, третьим параметром в функции стало число 9 (количество символов). Функция Copy возвращает результат такого копирования его можно присвоить некоторой строковой переменной (в примере MyString2)
var MyString1,MyString2:string;
begin
MyString1:= Моя программа;
MyString2:=Copy(MyString1, 5, 9);
writeln(MyString2);
readln;
end.
В результате работы программы переменной MyString2 присвоится значение «программа».
Пример 7.
Путем удаления символов получить из слова «программа» слово «гамма».
var MyString:string;
begin
MyString1:='Программа';
Delete(MyString,1,3);
Delete(MyString,2,1);
writeln(MyString);
readln;
end.
Первая процедура удаления (Delete(MyString,1,3);): из строки MyString удаляются три первых символа, теперь строка MyString имеет вид «грамма».
Вторая процедура удаления (Delete(MyString, 2, 1); удаляет из MyString один символ, начиная со второго. Т.е. удалится только второй символ, теперь строка MyString имеет вид «гамма».
Пример 8.
Путем вставки символов получить из слова «гамма» слово «программа».
Процедура Insert('р',MyString,2); вставляет букву «р» перед вторым символом строки MyString. Следующая процедура вставки Insert('про',MyString,1); вставляет строку «про» перед первым символом строки MyString, т.е. в начало строки. Обратите внимание, что в процедуре Insert первым параметром может быть не только строковая константа, но и строковая переменная, например, Insert(NewString,MyString,1). Вторым параметром может быть только переменная, поскольку именно второй параметр процедуры подлежит изменению, третьим параметром могут быть как константы, так и переменные целочисленных типов: Insert(NewString, MyString, k).
var MyString:string;
begin
MyString:='гамма';
Insert('р',MyString,2);
Insert('про',MyString,1);
writeln(MyString);
readln;
end.
Пример 9.
Пользователь вводит некоторый текст. Определить количество заглавных латинских букв, встречающихся в каждой строке этого текста.
var MyArray:array [1..100] of string;
n,count,i,j:byte;
s:string;
begin
writeln('введите текст, по окончанию - ***');
i:=0;
{ввод текста}
repeat
inc(i);
readln(s);
MyArray[i]:=s;
until (s='***');
n:=i-1; { n - количество строк}
for i:=1 to n do
begin
count:=0;
s:=MyArray[i];
for j:=1 to Length(s) do
if (s[j]>='A') and (s[j]<='Z') then inc (count);
writeln('в строке № ', i, ' количество = ', count);
end;
readln;
end.
В этой программе ввод текста организован следующим образом: пользователь вводит произвольные строки, окончанием ввода служит ввод строки «***». Массив строк задается большого размера, для того чтобы мог вместить все строки, которые введет пользователь. Затем, чтобы далее не перебирать все 100 элементов массива, вводится переменная n, равная количеству введенных строк. Из номера последнего элемента вычитается единица (n:=i-1;), чтобы исключить последнюю строку «***». Затем в цикле (по i) перебираются строки элементы массива, во вложенном цикле (по j ) перебираются элементы строк символы. Каждый элемент строки проверяется на соответствие условию задачи, при положительном исходе значение переменной count увеличивается.
В данной программе при вводе и обработке строк использовалась вспомогательная переменная s, но со строковыми элементами массива можно работать напрямую, нужно только принять во внимание, что MyArray[1], MyArray[2]… MyArray[i]… - это имена строковых переменных и работать с ними нужно как и с обычными строками.
var MyArray:array [1..50] of string;
n,count,i,j:byte;
begin
writeln('');
i:=0;
repeat
inc(i);
readln(MyArray[i]);
until (MyArray[i]='***');
n:=i-1;
for i:=1 to n do
begin
count:=0;
for j:=1 to Length(MyArray[i]) do
if (MyArray[i][j]>='A') and (MyArray[i][j]<='Z') then inc (count);
writeln('в строке № ', i, ' количество = ', count);
end;
readln;
end.
Пример 10.
Задана строка. Следует удалить из нее все знаки препинания.
Знаками препинания будем считать точку и запятую, количество знаков препинания может быть произвольным.
Следует обратить внимание на то, что цикл с параметром в задачах такого типа использовать нельзя, т.к. начальное и конечное значение параметра высчитывается только один раз при входе в цикл и не пересчитываются на каждой итерации, даже если начальное или конечное значение являются результатами вычисления некоторых выражений. При удалении символов длина строки уменьшается, при этом конечное значение параметра цикла остается неизменным, следовательно, происходит выход за границы строки. Если в настройках компилятора включена проверка границ (Range Checking на закладке Compiler), то выполнение следующего кода закончится ошибкой, если проверка границ не включена, то задача будет решена неправильно - удалятся не все знаки препинания.
var MyString :string;
i:byte;
begin
readln(MyString);
for i:=1 to length(MyString) do
if (MyString[i]=',')or (MyString[i]='.')
then Delete(MyString,i,1);
writeln(MyString);
readln;
end.
Потому при решении таких задач следует пользоваться циклами с условием.
Следующий код решает задачу корректно.
var MyString :string;
i:byte;
begin
readln(MyString);
i:=1;
while (i<=Length(MyString))do
begin
if (MyString[i]='.')or (MyString[i]=',')
then begin
Delete(MyString,i,1);
dec(i);
end;
inc(i);
end;
writeln(MyString);
readln;
end.
После выполнения лабораторной работы обучаемый должен:
Задание №1
A = {1,2,3,5,8,9}
B = {1,3,7}
C = {0,6,8,9}
Требуется: сформировать новое множество D (заштрихованная область на рисунке) и вывести полученное множество на экран.
A = {1,2,3,5,8,9}
B = {3,7,6,8}
C = {0,6,8,9}
Сформировать новое множество D (заштрихованная область на рисунке), вывести полученное множество на экран.
A = {1,2,3,5,8,9}
B = {0,1,3,6,7}
Сформировать новое множество С (заштрихованная область на рисунке), вывести полученное множество на экран.
A = {1,2,3,5,8,9}
B = {1,3,7}
C = {0,3,6,8,9}
Сформировать новое множество D (заштрихованная область на рисунке), вывести полученное множество на экран.
A = {1,2,3,7}
B = {1,2,3,5,8,9}
C = {0,6,8,9}
Сформировать новое множество D (заштрихованная область на рисунке), вывести полученное множество на экран.
A = {1,2,3,5}
B = {1,3,7,6,8}
C = {0,6,8,9}
Сформировать новое множество D (заштрихованная область на рисунке), вывести полученное множество на экран.
Задание №2
Пользователем вводится строка S. С помощью типа данных множество определить, содержит ли строка:
Задание №3
Задание №4
Задание №1
Пользователь вводит элементы трех символьных множеств А, В и С. Требуется: сформировать новое множество D (заштрихованная область на рисунке) и вывести полученное множество на экран.
Пользователь вводит элементы трех символьных множеств А, В и С. Требуется: сформировать новое множество D (заштрихованная область на рисунке), вывести полученное множество на экран.
Пользователь вводит элементы двух символьных множеств А и В. Требуется: сформировать новое множество С (заштрихованная область на рисунке), вывести полученное множество на экран.
Пользователь вводит элементы трех символьных множеств А, В и С. Требуется: сформировать новое множество D (заштрихованная область на рисунке), вывести полученное множество на экран.
Пользователь вводит элементы трех символьных множеств А, В и С. Требуется: сформировать новое множество D (заштрихованная область на рисунке), вывести полученное множество на экран.
Пользователь вводит элементы трех символьных множеств А, В и С. Требуется: сформировать новое множество D (заштрихованная область на рисунке), вывести полученное множество на экран.
Задание №2
С клавиатуры сформировать множество, состоящее из 10 чисел, элементы которого принадлежат промежутку 3 до 50. Выделить из полученного множества все числа, делящиеся на 5 и составить из них новое множество. Вывести его на экран.
Считать с клавиатуры два множества. Первое состоит из шести чисел, лежащих на промежутке от 0 до 10, второе из 3 чисел, лежащих на промежутке от 0 до 20. Найти их пересечение и вывести полученное множество на экран
С клавиатуры считать элементы двух множеств. Первое состоит из трех чисел, лежащих на промежутке от 0 до 10, второе - из пяти чисел лежащих на промежутке от 2 до 15. Сформировать новое множество, состоящее из общих элементов двух множеств, кратных трем. Вывести полученное множество на экран.
Из множества целых чисел 1..20 выделить: множество чисел, делящихся на 6 без остатка; множество чисел делящихся без остатка на 2 или на 3. Полученные множества вывести на экран
Считать с клавиатуры три множества. Первое состоит из четырех чисел, лежащих на промежутке от 0 до 20, второе из 3 чисел, лежащих на промежутке от 0 до 10, третье - из 3 чисел, лежащих на промежутке от 5 до 15. Сформировать новое множество, состоящее из четных элементов, входящих в эти множества. Вывести полученное множество на экран.
С клавиатуры сформировать множество, состоящее из 7 чисел, элементы которого принадлежат промежутку 10 до 30. Выделить из полученного множества все числа, делящиеся на 5 или на 7 и составить из них новое множество. Вывести его на экран.
Задание №3
Пользователем вводится строка S. С помощью типа данных множество определить:
Задание №4
Задание №5
Задание №6
Задание №1
С клавиатуры сформировать множество, состоящее из 10 чисел, элементы которого принадлежат промежутку 3 до 50. Выделить из полученного множества все числа, делящиеся на 5 и составить из них новое множество. Вывести его на экран.
Считать с клавиатуры два множества. Первое состоит из шести чисел, лежащих на промежутке от 0 до 10, второе из 3 чисел, лежащих на промежутке от 0 до 20. Найти их пересечение и вывести полученное множество на экран
С клавиатуры считать элементы двух множеств. Первое состоит из трех чисел, лежащих на промежутке от 0 до 10, второе - из пяти чисел лежащих на промежутке от 2 до 15. Сформировать новое множество, состоящее из общих элементов двух множеств, кратных трем. Вывести полученное множество на экран.
Из множества целых чисел 1..20 выделить: множество чисел, делящихся на 6 без остатка; множество чисел делящихся без остатка на 2 или на 3. Полученные множества вывести на экран
Считать с клавиатуры три множества. Первое состоит из четырех чисел, лежащих на промежутке от 0 до 20, второе из 3 чисел, лежащих на промежутке от 0 до 10, третье - из 3 чисел, лежащих на промежутке от 5 до 15. Сформировать новое множество, состоящее из четных элементов, входящих в эти множества. Вывести полученное множество на экран.
С клавиатуры сформировать множество, состоящее из 7 чисел, элементы которого принадлежат промежутку 10 до 30. Выделить из полученного множества все числа, делящиеся на 5 или на 7 и составить из них новое множество. Вывести его на экран.
Задание №2
Пользователем вводятся с клавиатуры элементы трех множеств А, В, С символьного типа. Сформировать новое множество . Вывести на экран полученное множество. Проверить включено ли множество С во множество D.
Во множестве, введенном пользователем с клавиатуры, содержатся как заглавные и прописные латинские буквы. Из этого множества сформировать два множества так, что в одном будут содержаться только заглавные буквы, а во втором только прописные. Вывести полученные множества на экран.
Считать с клавиатуры два символьных множества. Первое состоит из 10 букв, второе из 15. Вывести на экран в алфавитном порядке все буквы, которые входят в пересечение этих множеств.
Считать с клавиатуры два символьных множества, содержащих только русские и английские буквы. Первое состоит из 5 букв, второе из 6. Сформировать новое множество, которое будет состоять только из заглавных русских букв.
Считать с клавиатуры два символьных множества, содержащих только русские, английские буквы и цифры. Первое состоит из 4 букв, второе из 5. Сформировать новое множество, которое будет состоять только из строчных латинских букв.
Считать с клавиатуры два символьных множества. Первое состоит из 10 букв, второе из 4. Вывести на экран в обратном алфавитном порядке все буквы, которые входят в объединение этих множеств.
Задание №3
Вводится строка S. С помощью типа данных множество определить, является ли строка:
Задание №4
Таблица футбольного чемпионата задана следующим образом: известны названия 10 команд, каждой командой было проведено 9 матчей (Команду характеризует запись, одно поле которой - название команды, а второе - массив из 10 элементов. Каждый элемент равен 3, 1 или 0 (числу очков, набранных в игре: 3 выигрыш, 1 ничья, 0 проигрыш. Номер элемента массива определяет номер команды-соперника. Ясно, что первый элемент массива первой команды равен 0 и т.д.).
Количество мячей, забитых и пропущенных каждой из шестнадцати футбольных команд в каждой из 15 игр, записано в массиве. Его элементами величины типа запись. Названия команд известны.
Задание №5
Задание №6
Множество в языке Паскаль это ограниченный, неупорядоченный набор различных элементов одного типа. Рассмотрим определение более подробно:
Переменная типа множество объявляется в разделе объявления переменных следующим образом:
var <имя переменной> : set of <базовый тип>;
<имя переменной> должно отвечать правилам составления идентификаторов языка программирования Паскаль.
set of ключевые слова, предназначенные для объявления множеств.
<базовый тип> - тип элементов множества.
Пример 1.
Объявление переменных типа множество.
var MySet1 : set of char;
MySet2 : set of 'A'..'Z';
MySet3 : set of byte;
MySet4 : set of 20..50;
Обратите внимание, элементами обеих переменных-множеств MySet1 и MySet2 могут быть символы, но элементами множества MySet1 могут быть все символы (определяемые таблицей ASCII), а элементами MySet2 только заглавные английские буквы. При таком объявлении переменных определяется только тип элементов множества и количество памяти, которое необходимо выделить под переменные множества. Заполнение множества будет происходить в самой программе.
Аналогичная ситуация возникает и для переменных MySet3 и MySet4, MySet3 может содержать элементы из диапазона 0..255, а MySet4 - только элементы из диапазона 20..50.
В теле программы (разделе операторов) перед началом работы с переменными MySet1, MySet2, MySet3 и MySet4 необходимо определить их значение. Например:
MySet1:=[ '+' , '-' , 'A' , 'B' , '*' , 'c' , 'x' ];
MySet2:=[ 'A' .. 'D' ];
MySet3:=[ 0..9, 27,21 ];
MySet4:=[ ];
Квадратные скобки [ ] называют конструктором множества.
Элементы множеств можно записывать через запятую, если нужно включить в множество несколько подряд идущих элементов, например, буквы 'A', 'B', 'C', 'D' или цифры от 0 до 9, то можно указать их в виде диапазона 'A' .. 'D' или 0..9.
Множество MySet4 не содержит элементов, иначе говоря, является пустым множеством.
Таблица 6.1
Операция |
Описание |
= |
Равенство (эквивалентность, тождественность). Два множества считаются равными, если они состоят из одних и тех же элементов. При этом порядок следования элементов значения не имеет. |
<> |
Неравенство. Два множества считаются неравными, если они отличаются хотя бы одним элементом или их количеством. |
>= (>) |
Включение (строгое включение). Если все элементы множества В содержатся в множестве А, тогда результатом выражения А >= B будет значение True и говорят, что B является подмножеством А (содержится в А). |
<= (<) |
Включение (строгое включение). Если все элементы множества А содержатся в множестве B, тогда результатом выражения А <= B будет значение True и говорят, что A является подмножеством B (содержится в B). |
+ |
Объединением двух множеств является третье множество, содержащее элементы обоих множеств. [ 1, 2, 3, 4 ] + [ 3, 4, 5 ] = [ 1, 2, 3, 4, 5 ] |
* |
Пересечением двух множеств является третье множество, которое содержит элементы, входящие одновременно в оба множества. [1 ,2, 3]* [ 3, 4, 5 ] = [3] |
- |
Разностью двух множеств является третье множество, которое содержит элементы первого множества, не входящие во второе множество. [1, 2, 3] -[3, 4, 5] = [1, 2] |
in |
Используется для проверки принадлежности какого-нибудь значения указанному множеству. Оператор in часто позволяет значительно упростить сложные условные выражения. Например, следующий оператор if : if ( (i = 0) or (i = 1) or (i = 2)) and ((j= 3) or (j = 4) or (j = 5 ) ) then ... можно переписать в виде if (i in [0..2]) and (j in [3..5]) then ... |
Пример 2.
Пользователь вводит десять чисел из диапазона 0..255. Необходимо сформировать два множества: первое из первых шести чисел, второе из оставшихся четырех. Сформировать третье множество, являющееся пересечением этих множеств и вывести его на экран.
var s1,s2,res : set of byte;
i:byte;
x :integer;
begin
s1:=[]; s2:=[];
i:=0;
writeln('Введите элементы первого множества');
repeat
readln(x);
if (x>=0) and (x<=255)
then begin
s1:=s1+[x];
inc(i);
end
else writeln('неверное число');
until (i=6);
writeln('Введите элементы второго множества');
i:=0;
repeat
readln(x);
if (x>=0) and (x<=255)
then begin
s2:=s2+[x];
inc(i);
end
else writeln('неверное число');
until (i=4);
res:=s1*s2; {нахождение пересечения двух множеств}
write('Пересечение множеств равно ', '[');
for i:=0 to 255 do
if i in res then write(i, ' ');
writeln(']');
readln;
end.
Пользователь вводит число х, если это число удовлетворяет условию (x>=0) and (x<=255), то выполняется оператор s1:=s1+[x]. Запись s1:=s1+[x]; означает следующее: выполняется объединение множества s1 (операция +) с множеством, состоящим из одного элемента - [x], результат снова присваивается переменной s1, таким образом, происходит добавление элемента х к множеству s1.
Т.к. элементы множества не упорядочены и к ним нельзя обратиться по номеру, то вывод элементов множества происходит иначе, чем вывод на экран элементов массива. Следует в цикле перебрать все возможные значения элементов множества (в примере множества s1, s2 и res могут содержать элементы из диапазона 0..255), затем нужно проверить содержится ли каждый элемент в данном множестве, и если содержится, вывести его на экран.
for i:=0 to 255 do {перебираем все потенциальные элементы множества}
if i in res { проверяем содержится ли элемент во множестве}
then write(i, ' '); { если да- выводим на экран}
В предыдущем примере рассматривалось множество MySet2 : set of 'A'..'Z' множество заглавных английских букв. Пусть в разделе операторов оно некоторым образом заполняется (например, значения элементов вводит пользователь), для вывода на экран элементов множества MySet2, нужен следующий код:
for i:='A' to 'Z' do
if ( i in MySet2) then write(i, ' ');
где i переменная типа char.
Пример 3.
Пользователь водит строку, подсчитать количество строчных гласных букв.
uses SysUtils,Windows;
var MyStr:string;
i,count:integer;
begin
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
writeln('Введите строку');
readln(MyStr);
count:=0;
for i:=1 to length(MyStr) do
begin
if MyStr[i] in ['у', 'е', 'ы', 'а', 'о', 'э', 'я', 'и', 'ю']
then inc(count);
end;
writeln(count);
readln;
end.
Обратите внимание, что для корректной работы с русскими буквами нужно подключить модуль Windows и соответствующие функции (подробнее см. лабораторную работу №1). В отличие от предыдущих примеров в данном не объявляется переменная типа множество, а при проверке символов строки используется конструктор множества с необходимыми для решения задачи элементами: ['у', 'е', 'ы', 'а', 'о', 'э', 'я', 'и', 'ю']. Такой вариант работы с множествами очень распространен и используется в том случае, когда множество не нужно хранить или неоднократно к нему обращаться.
В отличие от массивов, которые используются для объединения однотипных данных, тип запись предназначен для объединения данных различных типов. Например, требуется хранить следующую информацию о сотрудниках фирмы:
Такие данные нельзя объединить в массив, т.к. они относятся к различным типам. Конечно, можно объявить пять различных переменных и работать с ними, но если потребуется хранить и обрабатывать информацию не по одному сотруднику, а например по трем, то работать с отдельными переменными будет неудобно. Поэтому объявим тип запись:
type Man=record
name : string;
dolgn : string;
data1 : word;
data2 : word;
pol : char;
end;
Man это название пользовательского типа данных (может быть произвольным), record ключевое слово, предназначенное для обозначения типа запись, далее следуют названия элементов записи (полей) с указанием их типов. Определение типа запись должно заканчиваться ключевым словом end.
Теперь можно объявить переменные типа запись:
var m1, m2, m3: Man;
К полю записи можно обратиться, указав сначала имя самой записи, потом через точку - название поля. Например:
m1.name
m2.pol
m1.data1 и т.п.
С полями записи можно выполнять все операции, определенные для величин данного типа. Например, m1.data1 целочисленная величина и работать с ней можно также как и с любой переменной целого типа.
С переменными типа запись в целом можно выполнять только операции присваивания: m1:=m2; все остальные операции выполняются с полями записи. Например, требуется организовать ввод данных по сотруднику с клавиатуры.
…
writeln(Введите ФИО сотрудника);
readln (m1.name);
writeln(Введите название должности);
readln (m1.dolgn);
writeln(Введите год приема на работу);
readln (m1. data1);
writeln(Введите год рождения);
readln (m1. data2);
writeln(Введите пол);
readln (m1. pol);
…
Для более удобной работы с полями записей предназначен оператор with. Синтаксис оператора with:
with <имя_записи> do <оператор>;
При этом в рамках <оператора> к полям записи с именем <имя_записи> можно обращаться только по названию поля. Обратите внимание, что в операторе with (как и в операторах for, while, if) можно выполнить только один оператор, поэтому, если нужно выполнить несколько операторов, следует использовать операторные скобки. Предыдущий пример можно переписать следующим образом:
…
with m1 do
begin
writeln(Введите ФИО сотрудника);
readln (name);
writeln(Введите название должности);
readln (dolgn);
writeln(Введите год приема на работу);
readln (data1);
writeln(Введите год рождения);
readln (data2);
writeln(Введите пол);
readln (pol);
end;
…
Пример 4.
Из трех сотрудников требуется найти сотрудника с максимальным стажем и вывести его фамилию на экран.
type Man=record
name : string;
dolgn : string;
data1 : word;
data2 : word;
pol : char;
end;
var m1, m2, m3: Man;
s1, s2, s3: integer;
begin
with m1 do
begin
writeln(Введите ФИО первого сотрудника);
readln (name);
writeln(Введите название должности);
readln (dolgn);
writeln(Введите год приема на работу);
readln (data1);
writeln(Введите год рождения);
readln (data2);
writeln(Введите пол);
readln (pol);
end;
with m2 do
begin
writeln(Введите ФИО второго сотрудника);
readln (name);
writeln(Введите название должности);
readln (dolgn);
writeln(Введите год приема на работу);
readln (data1);
writeln(Введите год рождения);
readln (data2);
writeln(Введите пол);
readln (pol);
end;
with m3 do
begin
writeln(Введите ФИО третьего сотрудника);
readln (name);
writeln(Введите название должности);
readln (dolgn);
writeln(Введите год приема на работу);
readln (data1);
writeln(Введите год рождения);
readln (data2);
writeln(Введите пол);
readln (pol);
end;
s1:=2008-m1.data1;
s2:=2008-m2.data1;
s3:=2008-m3.data1;
if (s1>s2) and (s1>s3) then writeln(m1.name, ' ', s1);
if (s2>s1) and (s2>s3) then writeln(m2.name, ' ', s2);
if (s3>s1) and (s3>s2) then writeln(m3.name, ' ', s3);
readln;
end.
Результат работы программы:
Если пользователь введет те же данные, что и на рисунке, то максимальный стаж будет у сотрудника с фамилией Петров и равен 12 лет.
Величины типа запись также как и величины стандартных типов могут быть объединены в массивы. Из предыдущего примера видно, что работа даже с тремя отдельными переменными не очень удобна и программа получается очень громоздкой. Перепишем программу с использованием массива величин типа запись.
Пример 5.
Из всех сотрудников фирмы требуется найти сотрудника с максимальным стажем и вывести его фамилию на экран.
type Man=record
name : string;
dolgn : string;
data1 : word;
data2 : word;
pol : char;
end;
var mass:array [1..100] of Man;
count,min, nmin,i : integer;
begin
writeln('Введите количество сотрудников');
readln(count);
for i:=1 to count do
begin
writeln('Введите ФИО ', i ,' -го сотрудника');
readln (mass[i].name);
writeln('Введите должность');
readln (mass[i].dolgn);
writeln(' Введите год приема на работу');
readln (mass[i].data1);
writeln('Введите год рождения');
readln (mass[i].data2);
writeln('Введите пол');
readln (mass[i].pol);
end;
min:=mass[1].data1;
nmin:=1;
for i:=2 to count do
if (mass[i].data1< min)
then begin
min:=mass[i].data1;
nmin:=i;
end;
writeln('Максимальный стаж ', mass[nmin].name, ' ', 2008-min);
readln;
end.
В данной программе вводится массив величин типа запись. Чтобы число сотрудников не было фиксированным (как в предыдущем примере) объявлен массив с большим количеством элементов (100). Теперь пользователь может сам определить количество сотрудников фирмы (переменная count). Поэтому конечное значение параметра циклов в программе равно не 100, а count, остальные, не заполненные элементы массива просто не рассматриваются.
С введением массива, код, предназначенный для организации вода данных по сотрудникам, намного сократился. Кроме того, поиск сотрудника с максимальным стажем свелся к поиску минимального элемента массива и его номера (т.к. чем раньше человек был принят на работу, тем больше его стаж).
После выполнения лабораторной работы обучаемый должен:
Задание №1
.
Значения х и y вводятся с клавиатуры.
Задание №2
Описать процедуру, которая
Задание №3
Задание выполняется для всех вариантов полностью.
Требуется описать процедуры MyInc и MyDec (аналогичные стандартным процедурам), которые имеют два параметра x и k, результатом выполнения процедур должно быть увеличение/уменьшение первого параметра на величину k.
Задание №1
Задание №2
Определить процедуры, необходимые для решения следующих задач:
Задание №3
Задание №1
Задание №2
Задание выполняется для всех вариантов полностью.
Задание №3
Определить процедуры и функции, необходимые для решения следующих задач:
Задание №4
Подпрограмма это фрагмент кода, к которому можно обратиться по имени. Она описывается один раз, а вызываться может столько раз, сколько необходимо. Одна и та же подпрограмма может обрабатывать различные данные, переданные ей в качестве аргументов. Подпрограммы нужны для того, чтобы упростить структуру программы и облегчить ее отладку. В виде подпрограмм оформляются логически законченные части программы.
В Паскале имеется два вида подпрограмм: процедуры и функции. Как уже упоминалось в материалах к лабораторной работе №1, в каждом языке программирования определен набор стандартных процедур и функций. Процедуры вызывается с помощью отдельного оператора, а функции в правой части оператора присваивания. Например,
inc(i); dec(i); {вызов процедур}
y:=abs(x); z:=cos(2*x)+sin(y); {вызов функций}
Иначе говоря, и в процедурах и в функциях выполняется некоторый набор операторов, при этом функция всегда должна вернуть некоторое значение. Например, функция abs(x) возвращает значение, равное модулю аргумента х, которое можно присвоить некоторой переменной, использовать при вычислении выражений или просто вывести на экран.
Синтаксис описания процедур и функций.
Описание подпрограмм должно находиться после раздела объявления переменных и до тела программы.
procedure <имя_процедуры> [(список параметров)]; { заголовок }
разделы описаний
begin
раздел операторов
end;
function <имя_функции> [(список параметров)] :
<тип_возвращаемого_значения>;
разделы описаний
begin
<имя_функции>:=<выражение>;
end;
Заголовок процедуры или функции начинается с соответствующего зарезервированного слова, далее задается имя подпрограммы (следует учитывать, что имя процедуры или функции является идентификатором языка Паскаль и должно отвечать правилам их составления). После имени подпрограммы в круглых скобках перечисляются параметры с указанием их типов, передаваемые в подпрограмму. Обратите внимание, что квадратные скобки в данном случае не являются элементом синтаксиса, а означают, что список параметров может отсутствовать.
Пример 1.
Требуется описать функцию, аналогичную стандартной функции abs(), вычисляющей модуль целого числа.
Назовем функцию MyAbs. Модуль числа вычисляется по формуле
Т.к. в задании требуется вычислить модуль целого числа, то параметр, передаваемый в функцию и возвращаемое значение будут типа integer.
Если при написании подпрограммы возникает необходимость использования вспомогательных переменных, их можно объявить внутри подпрограммы. Такие переменные называются локальными (в примере переменная res). Локальные переменные доступны только внутри тела той подпрограммы, в которой они объявлены и не видны в основной программе, а также других процедурах и функциях. Переменные объявленные в самой программе называются глобальными (в примере a и b).
Последним оператором в теле функции обычно является оператор <имя_функции>:=<выражение>;. Такой оператор обеспечивает возвращение функцией требуемого значения. В примере это оператор MyAbs:=res;.
Обратите внимание, что при объявлении функции параметр, передаваемый в нее называется z, а при вызове функции в нее передается переменная а. Параметры, которые указываются при объявлении подпрограммы называются формальными и играют роль псевдонимов для реальных (фактических) параметров. Иначе как узнать, переменную с каким именем передаст в подпрограмму пользователь? Во все подпрограммы можно передать переменные с произвольными именами, а в большинство подпрограмм и выражения. Например: z:=abs(x); z:=abs(y); y:=abs(d-2); y:=abs(sqrt(x)-z); и т.п.
Пример 2.
Описать функцию, которая проверяет, является ли число, переданное ей в качестве аргумента, кратным трем.
function Mod3(x:integer):boolean;
begin
if (x mod 3=0) then Mod3:=true else Mod3:=false;
end;
Т.к. функция должна определять кратно ли число трем или нет, то возвращаемое значение должно быть логического типа.
В данной функции не была использована локальная переменная, а имени функции присваивается одно из значений в зависимости от выполнения условия.
Пример 3.
Написать процедуру, которая выводит на экран элементы одномерного массива.
const n=10;
type TArray=array [1..n] of byte;
var a : TArray;
i:integer;
procedure PrintArray(mas:TArray);
var j:integer;
begin
for j:=1 to n do
write(mas[j],' ');
end;
begin
Randomize;
for i:=1 to n do
a[i]:=random(100);
PrintArray(a);
readln;
end.
Одним из способов передачи массива в качестве аргумента подпрограммы является объявление пользовательского типа (в примере TArraу). Для определения размера массива используется константа n, которая является границей цикла for и в процедуре, и в основной программе.
Замечание. При написании подпрограмм не рекомендуется использовать глобальные переменные и константы, если только они не переданы в качестве параметров, поскольку использование глобальных переменных в теле подпрограмм усложняет отладку программы и негативно влияет на ее читаемость.
Иначе говоря, подпрограммы следует писать таким образом, чтобы вся необходимая для их использования информация содержалась в заголовке. В разделе объявления локальных переменных должны быть описаны все служебные переменные, которые требуются подпрограмме для вычислений.
Какие проблемы могут возникнуть при использовании константы n в работе данной программы? Например, если предоставить пользователю возможность определять размер массива, то константа n должна быть достаточно велика, например n=1000.
const n=1000;
type TArray=array [1..n] of byte;
var a:TArray;
i,k:integer;
…
begin
writeln('Введите размер массива');
readln(k);
Randomize;
for i:=1 to k do
a[i]:=random(100);
…
end.
Возникает вопрос, как сообщить процедуре о действительном размере массива? В подобной ситуации следует передать его подпрограмме в качестве параметра.
const n=1000;
type TArray=array [1..n] of byte;
var a:TArray;
i,k:integer;
procedure PrintArray(mas:TArray; size:byte);
var j:integer;
begin
for j:=1 to size do
write(mas[j],' ');
end;
begin
writeln('Введите размер массива');
readln(k);
Randomize;
for i:=1 to k do
a[i]:=random(100);
PrintArray(a,k);
readln;
end.
Пример 4.
Написать процедуру, которая удваивает переданный в нее аргумент.
Процедуры и функции могут изменять значение переданных им параметров. Например, стандартная процедура для работы со строками Delete(s : string; ind, count : integer); меняет значение параметра s.
var y:real;
//-----------------------
procedure Double_(x:real);
begin
x:=x*2;
end;
//-----------------------
begin
readln(y);
Double_(y);
writeln(y:2:2);
readln;
end.
При запуске данной программы получим следующее:
Т.е. удвоения значения переменной, переданной в подпрограмму, не произошло. Почему? Способ передачи параметров в подпрограмму, который был приведен в предыдущих примерах, называется передачей по значению. Если в процедуру или функцию передается параметр-значение, то внутри подпрограммы создается копия этого параметра и все операции осуществляются только с копией, саму переданную переменную изменения не затрагивают (в примере переменную у).
Если в задаче требуется, чтобы произошло изменение самого параметра, то следует использовать параметры-переменные, которые передаются с ключевым словом var.
var y:real;
//-----------------------
procedure Double_(var x:real);
begin
x:=x*2;
end;
//-----------------------
begin
readln(y);
Double_(y);
writeln(y:2:2);
readln;
end.
Результат работы программы:
При передаче параметра с ключевым словом var, в подпрограмму передается не копия, а адрес переменной, поэтому изменения затрагивают переменную непосредственно.
Обратите внимание, что при передаче параметров переменных типы формальных и фактических параметров должны совпадать. При передаче параметров-значений типам параметров достаточно быть совместимыми по присваиванию. Т.е. в процедуру
procedure Double_(x:real);
begin
x:=x*2;
end;
можно передать параметры как вещественного так и целого типов, а в процедуре
procedure Double_(var x:real);
begin
x:=x*2;
end;
тип фактического параметра должен быть только real, передача переменных целых и других вещественных типов вызовет ошибку.
Пример 5.
Написать процедуру, которая выводит на экран строку, переданную ей в качестве параметра, указанное количество раз.
У данной процедуры должно быть два параметра:
procedure PrintN(s:string;n:byte);
var i:byte;
begin
for i:=1 to n do
writeln(s);
end;
Если в подпрограмму нужно передать произвольную строку, то можно воспользоваться типом string как и любым стандартным типом. Если же нужно передать строку ограниченной длины, то следует объявить пользовательский тип, например:
type MyString= string[20];
и в подпрограмму передавать аргумент типа MyString (аналогично примеру №3) .
?
(?,?)
?
(?,?)
?
(?,?)
?
(?,?)
?
(?,?)
?
(?,?)
?
(?,?)
?
?
(?,?)
?
(?,?)
?
?
(?,?)
?
?
(?,?)
?
(?,?)
?
?
(?,?)
?
?
(?,?)
(?,?)
?
z
w
h
(X0,Y0)
(X1,Y1)
r
(X2,Y2)
a
?
(?,?)
?
(?,?)
?
(?,?)
?
(?,?)
?
(?,?)
?
?
(?,?)
?
?
(?,?)
(?,?)
?
?
(?,?)
?
(?,?)
?
?
(?,?)
(?,?)
?
(?,?)
?
?
(?,?)
?
?
(?,?)
?
?
(?,?)
?
(?,?)
?