Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

CASEвыражение OF 4 страница



writeln(Rus('Корень уравнения Exp(x)=2 на отрезке от 0 до 10 равен '),x:10:8);

writeln(Rus('Значение функции в этой точке = '),f(x):10:8);

readln

end.

В результате выполнения программы получим корень х= 0.69314003. Теперь найдем пробелы в программе. Для этого вычислим корень уравнения ln(x)-50=0, a=1, b=1e30 - программа зациклится! Выведем внутри цикла значения a и b: эти числа почти одинаковы и не меняются, но поскольку их порядок 1021, b-a существенно превосходит наш отрезок. Есть два способа, которыми мы можем исправить положение. Первый заключается в правильном подборе отрезка, но надо понимать, что придется подбирать этот отрезок для каждого нового уравнения, то есть фактически для каждого уравнения писать свою программу. Очевидно, что это бесперспективный путь. Выведем в нашей зацикленной программе не только a и b, но и x, может быть, это поможет нам придумать второй способ: значение x, оказывается, в точности равно b.

Мы могли бы прийти к выводу, что рано или поздно x станет равным или a или b, рассуждая чисто теоретически. Действительно, на каждом шаге цикла мы уменьшаем отрезок в два раза; если бы мы работали на вещественной оси, то величины a и b стремились бы друг к другу бесконечно, но, поскольку множество вещественных чисел в компьютере дискретно (из-за конечного числа цифр), настанет момент, когда между a и b больше не будет ни одного числа. После этого выражение (a+b)/2 будет давать либо a, либо b. Воспользуемся этим обстоятельством и напишем следующуюпрограмму:

var a, b, epsilon, x, fa, fx: single;

function f(x:single):single;

begin f:= Ln(x)-50;

end; {f}

begin a: = 1; b: = 1e30;

fa:=f(a); x:=(a+b)/2;

while (x<>a)and(x<>b) do

begin fx:=f(x);

if fx=0

then begin writeln(x);

halt;

end;

if fa*fx<0

then b:=x

else a:=x;

x:=(a+b)/2;

end;

writeln(x); readln

end.

Программа дала верный результат 5.184705...E21.

Решим еще одну задачу: вычислить значения функции f(x)=ln(1+ln(1+exp(exp(x)))) на отрезке [0,1000] с шагом 5.

var x0, x1, h, x: single;

var i: byte;

function f(x:single):single;

begin f:=ln(1+ln(1+exp(exp(x))));

end; {f}

begin x0:= 0; x1:= 1000; h:= 5;

for i:=0 to round((x1-x0)/h) do

begin

x:=x0+i*h;

writeln('x=',x:4:0,' f(x)=',f(x));

end;

end.

При x=10 произошло переполнение. Означает ли это, что задача неразрешима? Нет, мы просто написали плохую программу, скопировав математическую формулу в оператор Паскаля. Посмотрим, в каком месте происходит переполнение - очевидно, при вычислении exp(exp(x)), других возможностей просто не существует. Это значит, что полученное значение exp(exp(x)) превосходит 1E38. Посмотрим на аргумент внутреннего логарифма: прибавление единицы к очень большому числу никак не изменит это число, следовательно, этой единицей можно пренебречь. Таким образом, для x≥5 наша формула упрощается:

f(x)=ln(1+ln(1+exp(exp(x))))=ln(1+ln(exp(exp(x))))=ln(1+exp(x))

Исправим программу:

function f(x:single):single;

begin if x<5

then f:=ln(1+ln(1+exp(exp(x))))

else f:=ln(1+exp(x));

end; {f}

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

19. Файлы. Работа с текстовыми файлами

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

Для работы с текстовым файлом в программе следует описать файловую переменную типа TEXT:

VAR f: TEXTFILE;

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

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

1. AssignFile(VAR f:TEXT; Name: String),

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

После этого для доступа к файлу выполняется открытие файла одной из трех процедур:

2. Reset(VAR f:TEXT) - открывает файл для чтения.

3. Rewrite(VAR f:TEXT) - открывает файл для записи.

4. Append(VAR f:TEXT) - открывает файл для записи в конец файла. Процедуры Reset и Append выполняются только для существующих файлов, процедура Rewrite - для любых файлов, но если файл существует, он будет уничтожен и создан заново. Чтение из файла и запись в файл выполняются процедурами READ[LN] и WRITE[LN], но перед списком ввода или вывода задается файловая переменная:

5. Read[Ln](VAR f:TEXT; список ввода ).

6. Write[Ln](VAR f:TEXT; список вывода ).

Списки ввода и вывода строятся точно так же, как и в случае ввода с клавиатуры и вывода на экран. Особенностью текстовых файлов является то, что они состоят из строк, каждая из которых заканчивается символом конца строки. Процедура WriteLn записывает в файл этот символ, а процедура Write - нет. Вы можете сами управлять длинами записываемых строк, в нужный момент вызывая процедуру WriteLn. При вводе следует помнить, что если символ конца строки не считан процедурой ReadLn, то следующая строка недоступна. Как правило, текстовый файл используется для хранения строк или символов, но можно держать там и числа.

Для текстовых файлов определены четыре логические функции:

7. Function EOLN(VAR f:TEXT):Boolean - возвращает TRUE, если при чтении достигнут конец строки.

8. Function EOF(VAR f:TEXT):Boolean - возвращает TRUE, если при чтении достигнут конец файла.

9. Function SeekEOLN(VAR f:TEXT):Boolean - возвращает TRUE, если в строке больше нет ничего, кроме пробелов.

10. Function SeekEOF(VAR f:TEXT):Boolean - возвращает TRUE, если в файле нет больше ничего, кроме пробелов.

Функция EOLN пригодится вам, если вы читаете из текстового файла символы; функция EOF - если вы читаете символы или строки, а функции SeekEOLN и SeekEOF необходимы при вводе чисел из текстового файла. Функции EOLN и SeekEOLN также могут быть полезны при обычном вводе с клавиатуры. Приведем пример: пусть необходимо ввести некоторый массив натуральных чисел и некоторый массив символов. Известно, что в обоих массивах не более 100 элементов. Запишем программу, которой не нужно заранее знать, сколько элементов будет введено, это удобнее, чем сначала запрашивать количество элементов в массиве.

const nmax=100;

var x: array[1..nmax] of word;

c: array[1..nmax] of char;

i, nx, nc: byte;

begin

nx:=0; nc:=0;

writeln(Rus('введите числа'));

{вводим все числа, заканчивая клавишей enter}

while not seekeoln do

begin inc(nx);

read(x[nx]);

end;

{считываем конец строки, иначе не введутся символы}

readln;

{вводим символы, заканчивая клавишей enter}

writeln(Rus('введите символы')); while not eoln do

begin inc(nc);

read(c[nc]);

end;

writeln(Rus('введено '),nx,Rus(' чисел:'));

for i:=1 to nx do

write(x[i]:8);

writeln;

writeln(Rus('введено '),nc,Rus(' символов:'));

for i:=1 to nc do

write(c[i]);

writeln; readln;readln;

end.

Вернемся к работе с файлами. Файл закрывается процедурой.

11. Procedure Close (VAR f: TEXT),

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

12. Procedure Erase (VAR f).

Удаляемый файл должен быть инициализирован, но не открыт, или открыт, но затем закрыт. Напишем программу, которая читает текстовый файл и выводит его на экран. Для ее работы нам понадобится создать при помощи любого текстового редактора файл, сохранить его под именем test.txt в той же папке, где будет храниться наша программа:

var f: textfile;

s: string;

const name='test.txt';

begin

assign(f,name);

reset(f);

while not eof(f) do

begin readln(f,s);

writeln(s);

end;

close(f); readln

end.

Теперь выполним то же самое, не используя строку:

var f: text;

c: char;

const name='test.txt';

begin

assign(f,name);

reset(f);

while not eof(f) do

begin

while not eoln(f) do

begin read(f,c);

write(c);

end;

readln(f);

writeln;

end;

end.

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

var f: text;

x: single;

const name='num.txt';

begin

assign(f,name);

reset(f);

while not seekeof(f) do

begin read(f,x);

write(x:10:5);

end; readln

end.

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





Дата публикования: 2014-11-04; Прочитано: 293 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.016 с)...