У нас: 141825 рефератів
Щойно додані Реферати Тор 100
Скористайтеся пошуком, наприклад Реферат        Грубий пошук Точний пошук
Вхід в абонемент


результати будуть ще несподіванішими. Але не захоплюйтесь, це може стати небезпечним для програми GreatBufferManager.

При виведенні в текст символи накопичуються у внутрішньому буфері, який скидається в зовнішній буфер у разі заповнення або виконання процедури writeln чи close. Можна також задати примусове скидання внутрішнього буфера тексту f викликом процедури FLUSH(f). Його варто записувати для періодичного виконання, а також після всіх виведень у файл. Підкреслимо, що за виклику процедури flush лише скидається внутрішній буфер у зовнішній. Скидання зовнішнього буфера при цьому відбувається лише у випадку його заповнення.

Якщо в кінці роботи з файлом не указати викликів flush чи close, то зміст внутрішнього буфера так і не потрапить у зовнішній буфер і у файл.

Приклад 2. Здається, наступна програма задає копіювання текстів:

program wrongcpy;

var f, g : text; c : char;

begin

assign(f, ...); assign(g, ...); reset(f); rewrite(g);

while not eof(f) do

begin read(f, c); write(g, c) end;

{тут не вистачає close(g) ! Хоча й close(f) не завадить...}

end.

Спробуйте цю програму запустити, і побачите, що якщо початковий файл – пісня, то файл-"копія" – теж пісня, але недоспівана. А все тому, що "кінець пісні" так і залишається у внутрішньому буфері.

Змінну під внутрішній буфер варто означати глобальною в програмі. Якщо означити та зв’ язати файлову змінну в програмі, а її внутрішній буфер означити у підпрограмі, то по закінченні виклику підпрограми файлова змінна буде доступною, а її буфер – ні. Спроба скидання з такого буфера по закінченні програми може призвести до непередбачених наслідків. Але якщо вся робота з файлом, від assign до close, описана в підпрограмі, то й буфер цілком природньо означити в ній же.

Приклад 3. Розглянемо програму з процедурою spoilbuf, тобто "зіпсувати буфер", за виклику якої змінюється буфер, що залишається в локальній пам’ яті після закінчення попередньої процедури fillbuf.

program foolish;

var f : text;

procedure fillbuf;

var buf : array[1..5]of char;

begin

settextbuf(f, buf); rewrite(f); write(f, 'abcdefgh');

end;

procedure spoilbuf;

begin end;

begin

assign(f, 'boo.dat'); fillbuf; spoilbuf;

close(f)

end.

При виконанні виклику fillbuf символи abcde заповнюють внутрішній буфер і скидаються в зовнішній. Потім, уже при виконанні close(f) вони з’ являються у файлі boo.dat. Але символи fgh залишаються у внутрішньому буфері після закінчення fillbuf і псуються під час виконання spoilbuf. Зіпсований буфер скидається при закриванні файла f, і потім замість fgh ми бачимо у файлі щось зовсім на них не схоже.

Задачі

15.1. Написати процедуру копіювання текстів із власними внутрішніми буферами розміром у 16 блоків, тобто 8192 байти, або 8K.

15.2. Написати процедуру побайтового порівняння текстів із власними внутрішніми буферами.

3. Буферизація екрана та клавіатури

Екран і клавіатура є текстами, зв’ язаними з файловими змінними output і input. Для роботи з ними також уживаються буфери.

Спочатку розглянемо екран. З ним зв’ язаний буфер, але символи, потрапивши в нього, одразу копіюються на екран. Якби цього не було, інформація на екрані з’ являлася би з небажаними затримками.

При виконанні процедури WRITE за значенням її кожного аргумента обчислюється стала, тобто послідовність символів, які через буфер одразу виводяться на екран. Насправді, виклик

write(E1, E2, … , EN )

виконується як послідовність викликів

write ( E1 ); write ( E2 ); … ; write ( EN ).

Виконання writeln відрізняється тим, що в буфер екрана "додається eol", і курсор переводиться в наступний рядок.

Організація роботи з клавіатурою набагато складніше. Символи, утворені натисканням клавіш, накопичуються в буфері клавіатури. Він уміщає 15 символів. У цьому можна переконатися, запустивши програму

uses crt;

begin delay(16000) end.

При її виконанні протягом 16 секунд неважко встигнути натиснути якусь клавішу 16 разів і за останнього натискання почути звуковий сигнал комп’ ютера, що свідчить про переповнення буфера клавіатури. Буфер переповнюється, оскільки за виконання цієї програми символи з нього не переносяться у внутрішній буфер. Крім того, набрані далі символи не відображаються на екрані і взагалі "зникають".

Перенесення символів у внутрішній буфер відбувається за виконання процедур читання readln і read. Як і для інших текстів, його розмір 128 байтів. У цьому можна переконатися, запустивши програму

begin readln end.

За її виконання комп’ ютер починає чекати натискань на клавіші. Кожне натискання на клавішу (крім Enter) приводить до появи відповідного символу в буфері клавіатури. Цей символ одразу переноситься в її внутрішній буфер та через екранний буфер без затримки відображається на екрані. Після того, як набрано 128 символів, наступний символ до внутрішнього буфера не переноситься й на екрані не з’ являється. Натомість можна почути звуковий сигнал, що свідчить про переповнення внутрішнього буфера.

Натискання на клавішу Enter веде до появи відповідного символу в буфері клавіатури та переведення курсора в новий рядок екрана. Коли цей символ з’ являється у внутрішньому буфері, рядок у ньому розглядається як "завершений символом eol".

Завершений рядок у внутрішньому буфері аналізується й за сталими в ньому обчислюються значення базових типів та присвоюються змінним, указаним у виклику read (readln). Якщо сталих менше, ніж змінних у виклику, то виконання продовжується, тобто внутрішній буфер спорожнюється та починається чекання нових символів із клавіатури.

Коли в черговому рядку проаналізовано останню сталу, поточним стає наступний за нею символ у внутрішньому буфері. Виконання процедури read на цьому закінчується. За наступного виконання процедури читання нові символи будуть додаватися до змісту внутрішнього буфера, але пошук і аналіз сталих почнеться від поточного символу буфера, що залишився від попереднього виклику read. Особливість процедури readln полягає в тім, що після аналізу останньої сталої решта символів у внутрішньому буфері


Сторінки: 1 2 3 4