Министерство общего и профессионального образования Российской Федерации РОСТОВСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ КАФЕДРА ...
12 downloads
363 Views
432KB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Министерство общего и профессионального образования Российской Федерации РОСТОВСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ КАФЕДРА ТЕОРЕТИЧЕСКОЙ И ВЫЧИСЛИТЕЛЬНОЙ ФИЗИКИ _______________________________________________________________
Т. П. Шестакова МЕТОДИЧЕСКИЕ УКАЗАНИЯ по курсу "Программирование и вычислительная физика" Часть I Основные конструкции языка Turbo Pascal. Простейшие типы данных
г. Ростов-на-Дону 2003 г.
2
Печатается по решению учебно-методической комиссии физического факультета. Протокол N от Шестакова Т. П. Методические указания по курсу "Программирование и вычислительная физика". Часть I. Основные конструкции языка Turbo Pascal. Простейшие типы данных. Заказ N
3
ВВЕДЕНИЕ Данная серия методических указаний содержат вводные сведения об операторах, процедурах и функциях языка Turbo Pascal. Предполагается, что студенты имеют некоторые навыки работы на компьютере, для ознакомления с которыми можно рекомендовать книгу [1]. Сейчас существует довольно много книг, посвященных программированию на языке Turbo Pascal. Полное описание всех процедур и функций языка можно найти, например, в книге [2]. При подготовке методических указаний ставилась цель сделать краткое изложение, которое может быть использовано студентами как при овладении основными приемами программирования на языке Turbo Pascal, так и в дальнейшей работе в качестве справочного материала. В каждом разделе приводятся небольшие учебные программы, демонстрирующие использование операторов, процедур и функций. В заключительной части приведены варианты заданий к каждому разделу, начиная с самых элементарных, сложность которых постепенно возрастает. В первой части обсуждаются наиболее простые конструкции языка − процедуры, обеспечивающие ввод-вывод данных, стандартные математические функции, условный оператор, операторы циклов, целочисленные и вещественные типы данных. СТРУКТУРА ПРОГРАММЫ НА ЯЗЫКЕ TURBO PASCAL Программа начинается с заголовка, который имеет следующий вид: Program <имя программы>; Слово program − зарезервированное, служебное слово, которое используется только для объявления имени программы. Имя программы, так же как имена используемых в программе констант, переменных, процедур, функций и т. д., называется идентификатором (поанглийски − identifier). Идентификаторы задаются программистом, при этом используются следующие правила: • идентификатор может состоять из букв латинского алфавита, цифр, знака подчеркивания; никакие другие символы в идентификаторе недопустимы; • идентификатор не может начинаться с цифры; • идентификатор не может совпадать ни с одним из зарезервированных слов; • длина идентификатора может быть произвольной, но значащими считаются первые 63 символа.
4
Как и любой оператор в языке Turbo Pascal, заголовок оканчивается точкой с запятой. Заметим, что заголовок программы является необязательным, и его можно опускать. За заголовком следует раздел описаний. Он содержит описание всех констант, переменных, типов данных, процедур, функций. Описание констант: сonst <имя константы> = <значение константы>; Описание переменных: var <имя переменной>: <тип переменной>; Простейшие типы данных: integer целочисленные данные от −32768 до +32767; занимают 2 байта; real вещественные данные, диапазон значений модуля от 2.9E−39 до 1.7E+38; точность представления данных − 11..12 значащих цифр; char символ, занимает 1 байт; string строка символов; boolean логический тип, занимает 1 байт и имеет два значения: false − ложь; true − истина. Часть программы, заключенная в фигурные скобки, представляет собой комментарий. Эта часть игнорируется компилятором и никак не отражается на работе программы. Альтернативно, комментарий можно ограничивать парой символов круглая скобка + звездочка. Далее следует раздел операторов − основная часть программы. Он ограничивается служебными словами begin и end. Простейшие операторы языка Pascal. Оператор присваивания: <имя переменной> := <значение переменной / результат вычисления выражения>; Оператор write/writeln выводит на экран значение константы, переменной или выражения. Действие оператора writeln отличается от оператора write тем, что оператор writeln после вывода информации переводит курсор на следующую строку. Оператор writeln без аргументов переводит курсор на следующую строку. Вещественные числа удобно выводить в формате:
5
<имя переменной>: <количество десятичных знаков>: <количество десятичных знаков после запятой> Для ввода информации с клавиатуры используется оператор read/readln. Как и в случае оператора writeln, оператор readln после ввода информации переводит курсор на следующую строку. Оператор readln без аргументов переводит систему в состояние ожидания, − работа программы прерывается и компьютер ждет нажатия клавиши ENTER. После этого программа продолжает работу. В конце программы ставится точка. Все, что вы напишете после точки, игнорируется компилятором. Program First; {Комментарий: это заголовок программы} (* Далее начинается раздел описаний *) const pi = 3.1415926; c0 = 10; var a1, a2, a3: integer; b1, b2, b3: real; c: char; d: string; {Конец раздела описаний} {Начало раздела операторов} begin {Операторы присваивания} a1 := 5; b1 := 2.1; c := 'A'; {Значения символьных и строковых переменных заключаются в апострофы: 'A'} a2 := 6 * a1; b2 := a1 + b1; b2 := a1 * b2; b3 := (a1 + a2) / ((b2 - b1) * 100); {Операторы вывода на экран} writeln('Это моя первая программа!'); {Этот оператор выводит на экран строковую константу 'Это моя первая программа!'. Той же
6
end.
цели можно достичь иначе, определив строковую переменную d} d := 'Это моя первая программа!'; writeln(d); {Вывод значений переменных} write(' a2 = ', a2); {На экран выводится строка ' a2 = ' и значение переменой a2} write(' b2 = ', b2); writeln(' b3 = ', b3); writeln(' c = ', c); writeln; {Перевод курсора на следующую строку} writeln(' b3 = ', b3:7:5); {Вывод вещественного числа с указанием общего числа десятичных знаков (в данном случае − 7) и числа знаков после запятой (в данном случае − 5)} {Далее следует ввод двух чисел с клавиатуры с последующим вычислением их суммы и выводом суммы на экран} writeln('Введите два числа: a1 и a2'); write(' a1 = '); read(a1); write(' a2 = '); readln(a2); a3 := a1 + a2; write('Сумма чисел a1 и a2: '); writeln(a3); readln; writeln('Это конец вашей первой программы!'); writeln; writeln;
АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ И СТАНДАРТНЫЕ МАТЕМАТИЧЕСКИЕ ФУНКЦИИ В языке Turbo Pascal имеются следующие арифметические операции: + сложение; вычитание; −
7
* / div mod
умножение; деление; целочисленное деление; получение остатка от целочисленного деления.
Стандартные математические функции языка Turbo Pascal: abs(x) абсолютное значение (модуль) числа; arctan(x) арктангенс; cos(x) косинус; exp(x) экспонента; frac(x) дробная часть аргумента; int(x) целая часть аргумента; ln(x) натуральный логарифм; pi значение числа π = 3,1415926...; sin(x) синус; sqr(x) квадрат аргумента; sqrt(x) квадратный корень. Аргументами всех функций (кроме функции pi, не имеющей аргумента) могут быть действительные и целые числа. Значениями всех перечисленных функций являются действительные числа. Функции преобразования типов: round(x) округляет действительное число до ближайшего целого; trunc(x) преобразует действительное число в целое путем отбрасывания дробной части. Аргументами этих функций являются действительные числа, значениями − целые. ord(x) возвращает код символа; аргументом является любой символ, значением − целое. chr(x) возвращает символ по заданному коду; аргументом является целое число от 0 до 255, значением − символ. Program Operations; var a: integer; x: real; begin x := 22 / 5; writeln(x:4:2); a := 22 div 5; writeln(a:1); x := 22 mod 5;
{На экран выводится 4.40} {На экран выводится 4}
8
end.
writeln(x:4:2); {На экран выводится 2.00} writeln; a := 3; x := sqrt(a); writeln('Квадратный корень из 3 равен ', x); writeln; write('Введите любое действительное число: '); readln(x); x := sqr(sin(x)) + sqr(cos(x)); writeln('Сумма квадратов синуса и косинуса равна ', x:4:2); writeln; writeln('Буква A латинского алфавита имеет код ', ord('A')); writeln('Буква B латинского алфавита имеет код ', ord('B')); writeln(chr(ord('A'))); {Печатает значение выражения chr(ord('A')) - букву A} readln;
УСЛОВНЫЙ ОПЕРАТОР Условный оператор в языке Turbo Pascal имеет следующий вид: if <условие> then <оператор 1, который нужно выполнить в случае, если условие справедливо> else <оператор 2, который нужно выполнить в случае, если условие нарушено>; Ветвь else в условном операторе может отсутствовать. if <условие> then <оператор, который нужно выполнить, если условие справедливо>; Если ветви then или else должны содержать более одного оператора, в качестве <оператор 1> и/или <оператор 2> следует использовать составной оператор begin <операторы> end
9
Служебные слова begin и end выполняют функцию операторных скобок, ограничивающих группу операторов. При употреблении условного оператора необходимо использовать следующие операции сравнения языка Turbo Pascal: = равно; <> не равно; < меньше; > больше; <= меньше или равно; >= больше или равно. Перечислим также логические операции в языке Turbo Pascal: not логическое не; and логическое и; or логическое или; xor исключающее или. Необходимо учитывать приоритет операции в языке Turbo Pascal: 1 not; 2 *, /, div, mod, and; 3 +, -, or, xor; 4 =, <>, <, >, <=, >=. В следующей небольшой программе использование условного оператора иллюстрируется на примере нахождения максимального из двух чисел. Program If_operator; var a, b, max: real; begin write('Эта программа находит максимальное '); writeln('из двух действительных чисел.'); writeln('Введите два числа: '); write(' a= '); readln(a); write(' b= '); readln(b); {Определение максимального числа и вывод его на экран} if a >= b then max := a
10
end.
else max := b; writeln('max= ', max); writeln; {Однако максимальное число может быть найдено и иначе, без использования ветви else условного оператора} max := a; if a < b then max := b; writeln('max= ', max); writeln; {Еще один вариант определения максимального числа с использование составного оператора} writeln(' a= ', a:7:3); writeln(' b= ', b:7:3); if a >= b then begin write('Значение переменной b '); write(' не превосходит значения '); writeln('переменной a.'); write('Максимальное значение '); writeln('равно ', a:7:3) end else begin write('Значение переменной '); write('меньше, чем значение '); writeln('переменной b.'); write('Максимальное значение '); writeln('равно ', b:7:3); end; {В последнем случае переменная max вообще не используется, поэтому этот способ экономичнее} readln;
ОПЕРАТОРЫ ЦИКЛОВ Оператор цикла for .. do: for <параметр цикла> := <начальное значение> to <конечное значение> do <оператор>;
11
Здесь <параметр цикла> − переменная целого или порядкового типа; <оператор> − любой оператор, в том числе составной, т. е. группа операторов, заключенных в "операторные скобки" begin .. end. Начальное и конечное значения могут быть вычисляемыми выражениями. При выполнении оператора for .. do переменной − параметру цикла − присваивается указанное начальное значение, затем проверяется условие, не превосходит ли параметр цикла указанное конечное значение. Если условие не выполняется, оператор for .. do завершает свою работу. В противном случае выполняются указанный оператор, после чего значение параметра цикла увеличивается на единицу, и цикл повторяется. Если начальное значение больше конечного, цикл не выполняется ни разу. Возможна другая форма оператора for .. do, когда при каждом исполнении цикла параметр цикла уменьшается на единицу: for <параметр цикла> := <начальное значение> downto <конечное значение> do <оператор>; Теперь начальное значение должно быть больше конечного или равно ему, иначе цикл выполняться не будет. Оператор цикла while .. do: while <условие> do <оператор>; Указанный здесь оператор (в том числе составной) циклически выполняется, пока справедливо указанное условие. Условие проверяется до выполнения оператора. Оператор цикла repeat .. until: repeat <операторы> until <условие>; Указанные здесь операторы выполняются, после чего проверяется указанное условие. Операторы повторяются до тех пор, пока не выполнено условие. При необходимости циклического повторения нескольких операторов, оператор repeat .. until не требует использования составного оператора (т. е. "операторные скобки" begin .. end можно не писать). Следующая программа демонстрирует работу операторов циклов на примере вычисления n! Поскольку n! − очень большое число даже при достаточно небольших значениях n, чтобы избежать ошибки переполнения при работе программы, здесь используется специальный тип представления целых чисел longint − long integer ("длинное целое"), который позволяет работать с целыми числами в диапазоне значений от −2 147 483 648 до +2 147 483 647. Тип INTEGER позволяет работать лишь с числами в диапазоне значений от −32 768 до +32 767.
12
Program Cycles; var n, i: integer; f: longint; {f = n!} begin writeln('Программа находит факториал числа.'); write('Задайте целое число от 1 до 10: '); readln(n); {Вычисление с помощью цикла for .. to с увеличением параметра цикла} f := 1; for i := 1 to n do f := f * i; writeln(n, '! = ', f); writeln; {Вычисление с помощью цикла for .. to с уменьшением параметра цикла} f := 1; for i := n downto 1 do f := f * i; writeln(n, '! = ', f); writeln; {Вычисление с помощью цикла while .. do} f := 1; i := 1; while i <= n do begin f := f * i; i := i + 1 end; writeln(n, '! = ', f); writeln; {Вычисление с помощью цикла repeat .. until} f := 1; i := 1; repeat f := f * i; i := i + 1 until i > n; writeln(n, '! = ', f); writeln;
13
end.
readln
ЦЕЛОЧИСЛЕННЫЕ ТИПЫ ДАННЫХ В языке Turbo Pascal имеется 5 целочисленных типов данных. В зависимости от типа переменная может принимать тот или иной диапазон значений. byte байт − длина 8 бит (без знака), диапазон значений − 0 .. +255; shortint короткое целое − длина 8 бит (1 бит − знак числа + 7 бит − двоичные цифры), диапазон значений − −128 .. +127; word слово − длина 16 бит (без знака), диапазон значений − 0 .. +65 535; integer целое − длина 16 бит (1 бит − знак числа + 15 бит − двоичные цифры), диапазон значений − −32 768 .. +32 767; longint длинное целое − длина 16 бит (1 бит − знак числа + 31 бит − двоичные цифры), диапазон значений − −2 147 483 648 .. +2 147 483 647. В зависимости от того, какой тип данных имеет переменная, ей будет отведена соответствующая область памяти при работе программы. Например, если нам известно, что целая положительная переменная при работе программы будет принимать значения, не превосходящие 255, нет смысла описывать эту переменную, как имеющею тип integer, более правильно использовать тип byte. Ошибки такого рода, хотя и влекут за собой нерациональное распределение памяти при работе программы, не должны приводить к неправильным результатам вычислений. Более опасны ситуации, когда значение переменной может выйти за пределы допустимого диапазона значений указанного типа. Например, рассмотрим следующий фрагмент программы: var b: integer; begin b := 1000; (* Это значение не превосходит 32767 *) b := 50 * b; (* b = 50000, что больше 32767 *) writeln ('b=', b:5) end.
14
В результате получим неправильное значение b = -15536. Для того, чтобы объяснить такой результат, нужно вспомнить, что компьютер работает с числами в двоичном представлении. Число 50000 в двоичной системе счисления есть 1100 0011 0101 0000. Поскольку это число типа integer, первый бит − 1 − указывает на знак числа, это число воспринимается как отрицательное. Отрицательные числа записываются в так называемом дополнительном двоичном коде, в котором 1100 0011 0101 0000 соответствует числу −15536. Иногда ошибки, вызванные тем, что значение числа превосходит допустимый диапазон, приводят к прерыванию работы программы и сообщению о переполнении (как в случае вычисления факториала числа, если соответствующая переменная не описана как longint). К данным целых типов применимы все арифметические операции, в частности, целочисленное деление div, получение остатка от деления mod, а также стандартные процедуры и функции: abs(i) вычисляет модуль i, i − выражение любого целого типа; chr(i) возвращает символ, соответствующий коду i, i − выражение типа byte (имеет значение от 0 до 255), результат имеет тип char; dec(i) уменьшает значение переменной i на 1, i − переменная любого целого типа; dec(i,j) уменьшает значение переменной i на целое число j, i − переменная любого целого типа; inc(i) увеличивает значение переменной i на 1, i − переменная любого целого типа; inc(i, j) увеличивает значение переменной i на целое число j, i − переменная любого целого типа; hi(i) возвращает старший байт аргумента, i − выражение типа integer или word, результат имеет тип byte; lo(i) возвращает младший байт аргумента, i − выражение типа integer или word, результат имеет тип byte; odd(i) принимает значение true (типа boolean), если i − нечетное число, и false − в противном случае; pred(i) возвращает предшествующее значение (i-1), i − выражение любого целого типа; random(i) возвращает псевдослучайное число из диапазона 0 .. (i-1), i − выражение типа byte; sqr(i) возводит в квадрат выражение i любого целого типа;
15
swap(i) succ(i)
меняет местами байты в значении выражения i, i − выражение типа integer или word; возвращает следующее значение (i+1), i − выражение любого целого типа.
Как пример работы с данными целого типа, приведем короткую программу, которая вычисляет сумму чисел целого числа. Чтобы программа могла работать с числами, состоящими из 1 − 10 цифр, используется тип longint. При нахождении суммы чисел используются операции целочисленного деления div и получения остатка от целочисленного деления mod (см. раздел 2). Program Integer_types; var n, i: longint; s: byte; {n - заданное число, i - вспомогательная переменная, s - сумма цифр числа. Она наверняка не превосходит 255, поэтому используется тип byte} begin write('Введите любое целое число, которое '); write('по модулю не превосходит '); writeln('2 147 483 647'); readln(n); i := n; s := 0; while i <> 0 do begin s := s + abs(i mod 10); i := i div 10 end; writeln('Сумма цифр ', n:9, ' равна ', s:3) end. ВЕЩЕСТВЕННЫЕ ТИПЫ ДАННЫХ В языке Turbo Pascal имеется 5 целочисленных типов данных. single длина 4 байт, 7 .. 8 значащих цифр, диапазон значений − 1E−45 .. 1E+38;
16
real
длина 6 байт, 11 .. 12 значащих цифр, диапазон значений − 1E−39 .. 1E+38; double длина 8 байт, 15 .. 16 значащих цифр, диапазон значений − 1E−324 .. 1E+308; extended длина 10 байт, 19 .. 20 значащих цифр, диапазон значений − 1E−4951 .. 1E+4932; comp длина 8 байт, 19 .. 20 значащих цифр, диапазон значений − 1E(−2*1063 + 1) .. 1E(2*1063 − 1). Возможность использования типов single, double, extended и comp требует наличия арифметического сопроцессора. Для обращения к арифметическому сопроцессору служит опция 8087/80287 (меню OPTIONS − COMPILER − NUMERIC PROCESSING − 8087/80287). При активной опции 8087/80287 (отмечается крестиком X) компилятор будет обращаться к арифметическому сопроцессору, и в программе можно использовать типы single, double, extended, comp. При неактивной опции 8087/80287 разрешается использовать в программе только тип real. Если компьютер не имеет сопроцессора, то его работу можно эмулировать (воспроизводить) с помощью специальных подпрограмм. Для подключения этих подпрограмм имеется опция EMULATION (меню OPTIONS − COMPILER − NUMERIC PROCESSING − EMULATION). Когда опция EMULATION активна, программа становится независимой от наличия сопроцессора. Если сопроцессор имеется, будут использоваться все его возможности; если сопроцессора нет, его работа будет воспроизводиться с помощью подпрограмм, и все вещественные типы данных можно использовать. Однако подключение дополнительных подпрограмм увеличивает объем программы. Если опция 8087/80287 неактивна, опция EMULATION игнорируется. С другой стороны, в текст самой программы можно включить так называемые директивы компилятора, которые могут включать ту или иную опцию или отменять ее действие. {$N+} директива использовать числовой сопроцессор (включает опцию 8087/80287); {$N-} директива не использовать числовой сопроцессор (отключает опцию 8087/80287); {$E+} директива включить режим эмуляции работы сопроцессора (включает опцию EMULATION); {$E-} директива отключить режим эмуляции работы сопроцессора (отключает опцию EMULATION). Сейчас уже практически все компьютеры имеют сопроцессоры. Если сопроцессор доступен, данные всегда обрабатываются в формате EXTENDED, а другие вещественные типы используются для экономии памяти.
17
Ниже приводится небольшая программа, в которой вычисляется значение функции sin ( x ) с заданной точностью ε с помощью бесконечного ряда. Считается, что требуемая точность достигнута, если вычислена сумма нескольких первых слагаемых, и очередное слагаемое оказалось по модулю меньше, чем ε. Это и все последующие слагаемые можно опустить. Результат сравнивается со значением, полученным с помощью стандартной функции языка Turbo Pascal sin ( x ) . Program Real_types; var epsilon, x, sqrx, s, sinus: extended; n: byte; begin write('Введите заданную точность: '); readln(epsilon); write('Введите аргумент функции: '); readln(x); sqrx := sqr(x); s := x; {Первый член ряда} n := 1; {Степень члена ряда} sinus := 0; {Сумма ряда} while abs(s) > epsilon do begin sinus := sinus + s; n := n + 2; s := - s * sqrx / ((n - 1) * n) end; write('Значение, вычисленное с помощью '); writeln('суммирования ряда: '); writeln(sinus:20:18); write('Значение, вычисленное с помощью '); writeln('стандартной функции: '); writeln(sin(x):20:18) end. Некоторые результаты. 1. Вычисление значения с различной точностью: Введите заданную точность: 1e-3 Введите аргумент функции: 0.1 Значение, вычисленное с помощью суммирования ряда: 0.100000000000000000 Значение, вычисленное с помощью стандартной функции: 0.099833416646828152
18
Введите заданную точность: 1e-5 Введите аргумент функции: 0.1 Значение, вычисленное с помощью суммирования ряда: 0.099833333333333333 Значение, вычисленное с помощью стандартной функции: 0.099833416646828152 Введите заданную точность: 1e-9 Введите аргумент функции: 0.1 Значение, вычисленное с помощью суммирования ряда: 0.099833416666666667 Значение, вычисленное с помощью стандартной функции: 0.099833416646828152 Введите заданную точность: 1e-12 Введите аргумент функции: 0.1 Значение, вычисленное с помощью суммирования ряда: 0.099833416646825397 Значение, вычисленное с помощью стандартной функции: 0.099833416646828152 2. Нарастание ошибки вычисления при увеличении аргумента (результат суммирования знакопеременного ряда): Введите заданную точность: 1e-7 Введите аргумент функции: 1 Значение, вычисленное с помощью суммирования ряда: 0.841471009700176367 Значение, вычисленное с помощью стандартной функции: 0.841470984807896507 Введите заданную точность: 1e-7 Введите аргумент функции: 10 Значение, вычисленное с помощью суммирования ряда: -0.544021064696450892 Значение, вычисленное с помощью стандартной функции: -0.544021110889369813 Введите заданную точность: 1e-7 Введите аргумент функции: 50 Значение, вычисленное с помощью суммирования ряда: 13.111823886413041800
19
Значение, вычисленное с помощью стандартной функции: -0.262374853703928787 Введите заданную точность: 1e-7 Введите аргумент функции: 70 Значение, вычисленное с помощью суммирования ряда: 9860810624.036733900 Значение, вычисленное с помощью стандартной функции: 0.773890681557889097 ЛИТЕРАТУРА
1. В. Э. Фигурнов, IBM PC для пользователя. Краткий курс, М., 1999. 2. В. В. Фаронов, Turbo Pascal 7.0. Начальный курс, М., Изд-во "Нолидж", 1998. 3. Л. А. Бугаев, Г. М. Чечин, К. Н. Жучков, Методические указания к проведению практических занятий по курсу "Информатика". Вып. 1.1. Необходимые определения и команды для работы на компьютере. Элементы языка Pascal (часть I), Ростов-на-Дону, УПЛ РГУ, 1998. 4. Л. А. Бугаев, Г. М. Чечин, К. Н. Жучков, Методические указания к проведению практических занятий по курсу "Информатика". Вып. 1.4.Задачи для самостоятельного решения на компьютере, Ростов-на-Дону, УПЛ РГУ, 1998.