Рассылка закрыта
При закрытии подписчики были переданы в рассылку "RFpro.ru: Программирование на языке Pascal" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
← Сентябрь 2004 → | ||||||
1
|
2
|
3
|
4
|
5
|
||
---|---|---|---|---|---|---|
7
|
8
|
9
|
10
|
11
|
12
|
|
13
|
14
|
15
|
16
|
17
|
18
|
19
|
20
|
21
|
22
|
23
|
24
|
25
|
26
|
27
|
28
|
29
|
30
|
Статистика
-5 за неделю
Pascal с нуля by [CPM] Выпуск №14
Информационный Канал Subscribe.Ru |
[Ø] Рассылка "Pascal с нуля" by [CPM]. Выпуск №14 [Ø]
::[Ø]BEGIN[Ø]::
Автор: v()v@#[CPM] mailto: vovanc@bigmir.net |
Intro
Доброе время суток, уважаемые подписчики!!
После долгого молчания хочу с радостью сообщить вам, что рассылка живёт, что
выпуски и
дальше будут выходить.
Очень трудно было вспоминать после месяца отдыха Паскаль. Пришлось поднимать
исходники,
читать статьи, долго и упорно вспоминать, напрягать мозги, чтоб обрести прежние
навыки программирования. Теперь я в форме и могу не только писать проги, но
и вести
рассылку!!!! Осталось только собрать всех остальных, т.е. MedL'a, Ustas'a,
но думаю, что этот выпуск сделаю с Ustas'ом. Куда без дизайнера? Вам ведь не
хочется
получить текстовую версию рассылки?
Итак, начнём наш выпуск. Я думаю, что не стоит повторять то, что мы уже учили,
ведь у вас
есть прошлые номера нашей рассылки, а если нет, то вы можете взять их тут:
http://subscribe.ru/archive/comp.soft.prog.pascalcpm
Этот выпуск будет посвящён работе с функциями, он будет больше, чем те, которые
выпускались,
потому что данная тема очень обширна и плюс ко всему мы ещё не рассмотрели все
способы
передачи параметров. Для вас это не будет сложно, если вы внимательно рассматривали
работу
процедур, о которой мы рассказывали в прошлом выпуске. Если вы недостаточно
хорошо поняли
изложенное в прошлом выпуске, то я советую вам повторно перечитать его. Этот
выпуск тоже
очень важен. Не освоить его - остаться на среднем уровне программирования, а
то и ниже,
если вы относились к ранним выпускам без должного внимания, а ведь это далеко
не весь
материал. Мы ещё не писали серьёзных программ, не изучали работу с файлами,
графику,
создание собственных модулей, некоторые типы данных и многое другое.
Функции. Часть Первая. Теория
"Образование не может заменить интеллект. Это неуловимое качество лишь отчасти может быть определено способностью решать загадки. Но заключается оно в способности творить новые загадки, отражающие то, о чём свидетельствуют чувства, выстраивая парадоксы определений". Фрэнк Герберт. Дом глав Дюны.
Определение.
Функция - это такая подпрограмма, результатом
выполнения которой обязательно является
некоторое значение.
Функции и процедуры очень похожи. Единственное существенное различие - то, что
функция возвращает какое-либо значение. Кроме того, результат её выполнения связывается
с её именем. Другими словами: функция предполагает обязательную передачу информации
в
программу. Она состоит из заголовка и тела ф-ии.
Рассмотрим заголовок ф-ии:
1) Заголовок начинается со служебного слова Function
2) После него идёт список передаваемых параметров в круглых скобках
(может отсутствовать)
3) Далее следует тип возвращаемого значения.
Общий вид описания заголовка функции:
Function [NAME] ([PARAMETRS]):[TYPE];
После заголовка идёт тело ф-ии. Оно может содержать свой блок объявления констант,
переменных, типов, после следует само тело функции.
Общий вид функции(скелет), включая заголовок:
Function [NAME] ([PARAMETRS]):[TYPE];
type
[TYPES]
var
[VARs]
const
[CONSTS]
begin
[OPERATORS]
end;
Сразу хочется заметить, что среди всех операторов в теле функции должен быть
оператор,
в котором имени функции присваивается значение для возврата.
Вызовы функции могут быть использованы в любых выражениях, как элементы вывода
в операторе вывода, как параметры в подпрограмме(процедуре, функции), хотя она
скорее
похожа на переменную, значение которой зависит от передаваемых параметров, доступная
только
для чтения; функции должны также стоять справа от знака присваивания. В этом
её отличие
от процедуры, вызов которой всегда представляет собой самостоятельный оператор.
Но ведь правила существуют для того, чтобы их нарушать! Начиная с Турбо Паскаля
версии 6.0
в его состав добавлена директива $X+, которая включает расширенный синтаксис.
Она
позволяет использовать функцию как процедуру, то есть игнорируется возвращаемое
значение и
её вызов может представлять самостоятельный оператор. Также это директива включает
поддержку строк, завершающихся нулём, которые могут быть длиной до 65535 символов!!!
Подробней почитайте в Help'е. На этом, я думаю, не стоит останавливаться, это
не сложно.
Также хочется сказать, что способы передачи параметров функциям и процедурам одинаковы.
Функции. Часть Вторая. Практика
"Многое из того, что мы делаем естественно, становится сложным только тогда, когда мы превращаем это в предмет приложения нашего интеллекта. Возможно знать о предмете столько, что станешь совершенно невежественным". Фрэнк Герберт. Дом глав Дюны.
Я буду писать примеры с объяснениями в том порядке, в котором они изложены
в теории:
заголовок функции, тело.....
Заголовок.
Function CPM(var x:integer; y:word): boolean;
Функция, имя которой CPM, в которую передаются 2 параметра: один передаётся
по ссылке,
второй - по значению. Возвращает эта функция результат типа Boolean (true, false).
Теперь самостоятельно разберите эти две функции, вернее их заголовки:
1) function CMPStrings(var str1,str2:string): boolean;
2) function GetHour: byte;
Общий вид функции, простейшая функция.
function summa(first,second:integer): longint;
var
result: longint;
begin
result:= inc(first,second);
summa:= result; {!!!!!!!!!!!!!!!!!!!!!!!!}
end;
Главное в программировании - использование интуитивно понятных имён функции,
процедур,
переменных.... В нашем случае уже из названия видно, что речь пойдёт о сложении
чего-то с чем-то. Если мы посмотрим на список передаваемых параметров, то сможем
увидеть, что в функцию передаётся два параметра типа integer, а возвращаемое
значение -
longint. Дальше мы видим блок объявления переменных (создан для наглядности).
Также могут
присутствовать блоки объявления типов и констант. Дальше в этой простейшей функции
ищется
сумма первого и второго параметра, а результат помещается в локальную переменную
типа
longint. После этого в переменную с именем функции заносится значение суммы,
что является
возвращаемым значением (помечено восклицательными знаками). Строки
result:= inc(first,second);
summa:= result;
можно заменить одной
summa:=inc(first,second);
В функции обязательно должен быть оператор присваивания, при чём слева от знака
присваивания должно идти имя функции, а слева - значение или выражение (типы
должны
совпадать или должна выполнятся операция приведения типов).
Несколько примеров использования функций, сравнение процедуры с функцией.
Как же использовать функции? - Очень просто!
0) Создаём функцию
function minimum(x,y:integer): integer;
begin
if x>y then minimum:=y else minimum:=x;
end;
1) Используем
а) как значение, присваиваемое переменной (в нашем случае переменная должна
быть типа
integer.
x_int:= minimum(5,2);
переменной x_int будет присвоено значение 2.
б) в любых выражениях
x_int:=5+3*minimum(x1_int,x2_int);
в) как элемент вывода в операторе вывода
write(minimum(x1_int,x2_int));
на экран будет выведено значение одной из переданных переменных
г) как параметр, передаваемый в функцию или процедуру.
x1_int:=minimum(1,2);
x2_int:=minimum(3,4);
x_int:= minimum(x1_int,x2_int);
тут мы с помощью функции нахождения минимального из двух чисел нашли минимальное
из 4.
Это можно было сделать проще:
x_int:= minimum(minimum(1,2),minimum(3,4));
С использованием функций разобрались, но если есть вопросы - пишите, мой мейл ниже.
Для сравнения функции с процедурой напишем две программы, которые должны выполнять
одно
действие - выводить максимум из двух чисел. Одна должна делать это с помощью
функции, а
вторая - процедуры.
0)
uses crt;
var
x,y:real;
{переменные для ввода}
function maximum(a,b:real):real;
begin
if a>b then maximum:=a else maximum:=b;
end;
{Функция}
begin
clrscr;
{традиционное начало}
WriteLn('Введите два числа');
ReadLn(x,y);
{получить два числа}
WriteLn(maximum(x,y));
{вывести максимальное, используя функцию, как элемент вывода}
readkey;
end.
1)
uses crt;
var
x,y:real;]
{переменные для ввода}
procedure maximum(a,b:real);
begin
if a>b then WriteLn(a) else WriteLn(b);
end;
{процедура}
begin
clrscr;
WriteLn('Введите два числа');
ReadLn(x,y);
{получить два числа}
maximum(x,y);
{вывести максимальное}
readkey;
end.
Что всё-таки лучше использовать?
Как по мне следует оформлять подпрограмму как функцию стоит в том случае, когда
от её
работы ожидается какой-либо результат или вы собираетесь использовать её в выражениях.
Если же подпрограмм должна просто выполнять последовательность действий, то
лучше
оформить её в виде процедуры. Если же вам нужны функция и процедура со схожими
предназначениями, например, вам надо процедура, которая сортирует массив и функция,
которая сортирует массив и возвращает минимальное значение - можно использовать
функцию, как процедуру, заюзав директиву $X+.
Рассмотрим пример её использования:
{$X+}
{Включаем расширенный синтаксис Паскаля (6.0 и выше) соответствующей директивой}
uses crt;
var
x,y:real;
{переменные для ввода}
function maximum(a,b:real):real;
begin
if a>b then begin
WriteLn(a);
maximum:=a;
end
else begin
WriteLn(b);
maximum:=b;
end;
end;
{функция выводит максимум и возвращает максимум}
begin
clrscr;
WriteLn('Введите два числа');
ReadLn(x,y);
{получить два числа}
maximum(x,y);
{юзаем как процедуру - выведет минимум из двух введённых}
WriteLn;
WriteLn;
{для наглядности}
x:=maximum(10,15);
{юзаем как функцию - на экран выведется 15}
write(x);
{проверяем, а действительно ли всё в порядке (в переменной х должно быть 15)}
readkey;
end.
Для выхода из подпрограммы в произвольном месте используёте команду EXIT
Procedure WasteTime;
Begin
Repeat
If KeyPressed Then Exit;
Write('Xx');
Until False;
End;
Begin
WasteTime;
writeln('Нагло содрано с HELPa');
End.
Функции и процедуры. Передача параметров(продолжение)
"Готовность понять - чаще всего просто рефлекторная реакция и наиболее опасная форма понимания. Она - теневой экран на вашей способности учиться. Некоторые законы функционируют именно так,загоняя вас в тупик. Будте осторожны. Ничего не понимайте. Всё понимание временно". Фрэнк Герберт. Дом глав Дюны.
В прошлой статье я рассказывал про передачу параметров в процедуры. Я рассматривал
передачу
массива, передачу по значению, передачу по ссылке. Как упоминалось выше -
способы передачи параметров в процедуры и функции одинаковы. Но мы ещё упустили
несколько
способов передачи.
Бестиповые параметры-переменные.
При данном способе передачи параметров передаваемым(фактическим) параметром
может быть
любая переменная или константа произвольного типа. Нельзя передавать выражение,
так как при данном способе передача параметров происходит по ссылке, то есть
в
подпрограмму передаётся не значение переменной(константы), а её адрес в памяти.
Приведём пример описание формального бестипового параметра.
procedure Some(var some; x:integer);
В данном случае some - имя формального бестипового параметра.
Очень важно иметь понятие о том - что такое формальный, а что такое фактический
параметр.
Если вы до сих пор этого не поняли - перечитайте ещё раз то, что написано выше
про
бестиповые параметры.
Объединяя всё вышесказанное в одно очень дурное определение, получаем что-то
типа этого:
Если вы объявили формальный бестиповый параметр, соответствующий ему фактический
параметр
может быть ссылкой на переменную или типизированную константу произвольного
типа.
Было бы всё хорошо, если бы мы знали с параметром какого типа работаем в подпрограмме,
но там мы имеем бестиповый параметр - он не совместим ни с какой переменной
какого-либо
типа, это означает, что мы не можем её использовать ни в каких конструкциях или
выражениях.
Есть два типа преодоления этой проблемы:
0) Использовать операцию приведения типов
Function cmp_val(var v1,v2; size:word):boolean;
{функция сравнивает значения двух переменных любого типа}
type
bytes = array [1..65000] of byte;
{задаём тип (будет использоваться в операциях приведения типов), размер элемента
- byte,
так как будем сравнивать побайтно}
var
i:word;
{переменная-счётчик (для цикла)}
begin
cmp_val:=true;
{пока что у нас всё совпадает, но если мы найдём хоть один байт первой переменной,
который не совпадает с соответствующим ему байтом второй переменной, это строка
превратится
в такую: cmp_val:=false;}
for i:=1 to size do
if bytes(v1)[i] <> bytes(v2)[i] then begin
cmp_val:=false;
exit;
end;
{побайтно сравниваем переменные, используя операцию приведения типов. Фактически
мы
сравниваем два массива array [1..65000] of byte, но сравниваем только size элементов.
Если хоть не совпадают, то возвращаем ЛОЖЬ и выходим, юзая EXIT}
end;
var
s1,s2,s3:string;
x,y:word;
{переменные значения которых будем сравнивать}
begin
x:=9999;
y:=9999;
s1:='CPM forever';
s2:='CPM rulez';
s3:='CPM rulez';
{начальные значения для сравнения}
writeln;
{для красоты}
writeln(cmp_val(s1,s2,length(s1)));
{сравниваем первые две строки. Функция length возвращает длину строки, имя которой
указано в скобках. На экране должна появиться строка 'FALSE'}
writeln(cmp_val(s3,s2,length(s2)));
{сравниваем две одинаковых строки. На экране - 'TRUE'}
writeln(cmp_val(s1[1],s2[1],4));
{Сравниваем первые 4 символа первой и второй строк: 'CPM ' и 'CPM '. На экране
'TRUE'}
writeln(cmp_val(s1[5],s2[2],4));
{Сравниваем символы с 5-ого по 9-ый первой строки и со 2-ого по 6-ой второй
строки.
На экране 'FALSE'}
writeln(cmp_val(x,y,sizeof(word)));
{Две переменные типа word. Функция sizeof возвращает размер (в байтах) типа
в скобках.
На экране 'TRUE'}
readln;
end.
1) Описать локальную переменную конкретного типа и связать её в памяти с бестиповым
параметром.
Я могу просто скопировать предыдущую программу, немного скорректировать её и
получить
программу, иллюстрирующую данной способ обхода вышеописанной проблемы, но я
хочу показать некий подводный камень, с которым вы можете столкнуться, юзая
бестиповые
параметры и поэтому напишу здесь другую программу.
uses crt;
procedure copy_val(var v1,v2; size:word);
{на этот раз я решил сделать процедуру с бестиповым параметром. Эта процедура
копирует содержимое одной переменной произвольного типа в другую.}
type
bytes = array [1..65000] of byte;
{опишем тип. просто так}
var
_v1:bytes absolute v1;
_v2:bytes absolute v2;
{два локальных байтовых массива, которые содержат в себе передаваемые переменные,
разбитые
на байты}
i:word;
{переменная-счётчик}
begin
for i:=1 to size do
_v2[i] := _v1[i];
{у нас два массива. копирование одного в другой мы уже проходили}
end;
var
s1:string[11];
{переменная для отловки подводного камня}
s2,s3:string;
{ещё две для того, чтоб показать принцип работы}
begin
clrscr;
s1:='CPM forever';
s2:='CPM rulez forever';
s3:='CPM rulez';
{начальные значения}
writeln;
copy_val(s1,s3,length(s1)+1);
writeln('s1=',s1);
writeln('s2=',s2);
writeln('s3=',s3);
writeln;
{копируем значение первой строки в третью, результат на экране. всё в порядке}
copy_val(s2,s3,length(s2)+1);
writeln('s1=',s1);
writeln('s2=',s2);
writeln('s3=',s3);
writeln;
{копируем значение второй строки в третью, результат на экране. всё в порядке}
copy_val(s2,s1,length(s2)+1);
writeln('s1=',s1);
writeln('s2=',s2);
writeln('s3=',s3);
{копируем значение второй строки в первую и видим, что нас ждёт огромный облом.
вторая строка искажена. это связано с тем, что вторая строка в сегменте данных
расположена сразу после первой. Под первую зарезервировано 11 байт, а под вторую
255.
Когда мы пытаемся копировать 17 байт второй строки в 11 байт первой, то мы вылазим
за предел первой и записываем оставшиеся 6 байт с s2[0] по s2[5], что приводит
к искажению
второй строки, которая становится вида 'reverulez forever', а после этой надписи
идёт ещё
94 пробела. Дело в том, что в s2[0] хранится кол-во букв в строке s2, но при перезаписи
туда попадает код буквы 'o', который равен 111, после этого вторая строка выводится
не как строка из 17 букв, а как строка из 111 букв}
readkey;
end.
Данный способ передачи параметров даёт вам практически полную свободу действий
при передаче
параметров, но, как видите тут есть и свои "подводные камни", которые
нужно уметь обходить.
Для того, чтобы начать изучения следующего типа передачи параметров нам надо
определиться с
понятием процедурного типа.
Процедурный тип. Переменные процедурного типа.
Turbo Pascal позволяет рассматривать подпрограммы как объекты, что даёт возможность
присвоить таковую переменной или передать в качестве параметра подпрограмме.
Для
того, чтоб заюзать эту возможность есть такая штуковина, как процедурный тип.
Как
и все остальные типы, процедурный тип объявляется в разделе объявления типов
(type).
Рассмотрим общий вид описания процедурного типа.
type
[NAME] = procedure([PAR]);
{тип для процедуры}
[NAME] = function([PAR]):[TYPE];
{для функции}
Описание процедурного типа очень похоже на описание заголовка подпрограммы.
Рассмотрим несколько примеров описания процедурного типа.
type
MyFirst = function(x,y:integer):longint;
procCPM = procedure(var v1,v2; s:integer);
NULPar = procedure;
OBANA = procedure(var x,y:byte; summa:MyFirst);
Имена параметров не имеют в дальнейшем никакого значения. Значение имеют только
типы.
Когда мы определили процедурный тип, мы можем определять переменные данного
типа.
Несколько примеров:
var
s: MyFirst;
OPA: OBANA;
Переменным процедурного типа, как и переменным любого другого типа можно присвоить
какое - либо значение. Это может быть идентификатор (имя) подпрограммы или переменная
такого же процедурного типа.
Несколько примеров:
s:=summa;
OPA:=TADA;
После таких действий мы можем сделать вызов функции summa так:
s(x,y);
или процедуры TADA так:
OPA(a,b,s);
Как я уже говорил - имена параметров не имеют значения, но как и в случае с
любыми
переменными важное значение играют типы. Чтоб присвоить процедурной переменной
значение
другой процедурной переменной или идентификатора нужно:
0) процедурные типы должны иметь одинаковое количество параметров
1) параметры в соответствующих позициях должны быть одного типа
10b) для функций - возвращаемые значения должны быть одного типа
11b) подпрограмма должна быть объявлена как far или откомпилирована с директивой
$F+
100b) не должна быть стандартной процедурой или функцией
101b) не должна быть вложенной interrupt или inline (об этом ниже) подпрограммой
Переменная процедурного типа хранит адрес подпрограммы в памяти и занимает
4 байта - 2
под сегмент, 2 под смещение.
Теперь перейдём непосредственно к параметрам процедурного типа.
Как передать параметр процедурного типа?
0ffh) Создать процедурный тип
0feh) Создать подпрограмму под этот тип или переменную
0fdh) Создать подпрограмму, в которую надо передать параметр данного процедурного
типа
0fch) Передать идентификатор или переменную процедурного типа как параметр в
подпрограмму.
Напишем программу, которая проиллюстрирует вышесказанное:
uses crt;
const
n=10;
{число элементов в массиве}
type
ArrCPM = array[1..n] of integer;
{тип под массив, чтоб можно было передавать в процедуры}
ProcCPM = procedure(x,y:word; var v:ArrCPM);
{процедурный тип}
{$F+}
{директива, которая делает подпрограммы "дальней" - чтоб использовать
эти процедуры как
параметры}
Procedure min(a,b:word; var g:ArrCPM);
var
temp:integer;
begin
if g[a]>g[b] then begin
temp:=g[b];
g[b]:=g[a];
g[a]:=temp;
end;
end;
Procedure max(a,b:word; var g:ArrCPM);
var
temp:integer;
begin
if g[a]<g[b] then begin
temp:=g[b];
g[b]:=g[a];
g[a]:=temp;
end;
end;
{Процедуры, которые передаем в процедуру сортировки. Первая переставляет в начало
массива
минимальный элемент, а вторая - максимальный}
{$F-}
{дальше нам не нужна эта директива}
procedure sort(var a:ArrCPM; f:ProcCPM);
{процедура сортировки. сортирует по убыванию или возрастанию в зависимости
от
передаваемой процедуры}
var
i:word;
j:word;
{переменные под счётчик}
begin
for i:=1 to n-1 do
for j:=i to n do
f(i,j,a);
{в алгоритме сортировки тут должна быть проверка и перемена мест элементов,
которая у нас забита в соответствующие процедуры. Что и определяет порядок сортировки}
end;
{подпрограммы закончились. Ниже - тело программы}
var
somearr:ArrCPM;
{массив}
i:word;
{под счётчик}
begin
randomize;
{генератор}
clrscr;
{чистим}
for i:=1 to n do somearr[i]:=random(2000)-999;
{заполняем массив}
for i:=1 to n do write( somearr[i]:5);
{выводим на экран}
writeln;
sort(somearr,min);
{сортируем по возрастанию}
for i:=1 to n do write( somearr[i]:5);
{выводим на экран}
sort(somearr,max);
{Сортируем по убыванию}
writeln;
for i:=1 to n do write( somearr[i]:5);
{выводим}
readkey;
end.
{Конец}
Я советую вам поэкспериментировать со всеми типами передачи параметров подпрограммам,
это даёт вам очень большие возможности в программировании, существенно облегчая
процесс.
Если вы думаете, что это конец выпуска - вы ошибаетесь. Мы не рассмотрели ещё
одно -
объявления подпрограмм, а это ещё несколько килобайт текста. Как подумаю, что
всё это
писать мне - хочется выпить кофе.
Объявление подпрограмм.
Общий вид описания подпрограммы с объявлением:
[заголовок]; [объявление];
Часть 1. NEAR and FAR.
Существует две модели вызова, которые поддерживает Язык Турбо Паскаля - near и far (ближняя и дальняя). У каждой из них свои преимущества и недостатки. Ближний вызов процедуры выполняется быстрее и занимает меньше места по сравнению с дальним. Дальний же вызов можно вызывать из любого модуля, в то время, когда ближние могут быть вызваны только из того модуля, в котором они объявлены. Процедуры, объявленные в программе имеют ближнюю модель вызова и могут использоваться только внутри программы.
В некоторых случаях использование дальней модели вызова просто необходимо, например, когда надо присвоить подпрограмму переменной процедурного типа. Для указания дальней модели вызова можно использовать директиву $F, которая в состоянии $F+ активирует дальнюю модель вызова, а в состоянии $F- включает режим, в котором Паскаль автоматически определяет (не всегда корректно) модель вызова. По умолчанию $F-.
{$F+}
[подпрограмма]
{$F-}
В этом случае активируется дальняя модель для вызова данной подпрограммы.
Для задания требуемой модели заголовок подпрограммы может содержать директивы near или far. Они перекрывают установку директивы $F и автоматический выбор модели компилятором.
Часть 2. Forward (опережающее объявление).
Если для подпрограммы включена эта директива, то её вызов может быть сделан в теле другой
подпрограммы. Для того чтобы сделать опережающее объявление подпрограммы, надо:
0) описать заголовок подпрограммы с указанием директивы Forward.
1) в том же блоке программы, где описан этот заголовок (не обязательно сразу после
него) создать подпрограмму с точно таким же заголовком.
После этих нехитрых действий можно делать вызов данной подпрограммы в теле другой подпрограммы. Ниже небольшой пример.
Function summa(x,y:integer):longint; Forward;
Function raznost(x, y: integer): longint;
Begin
raznost:=summa(x,-y);
End;
Function summa(x, y: integer): longint;
Begin
summa:=inc(x, y);
end;
....
Если появятся вопросы, присылайте их мне или кому-нибудь из команды на ящик. Все остальные объявления подпрограмм мы рассмотрим по мере надобности.
На этом заканчиваю этот выпуск. Думаю, что вам хватит материала на следующие 1-2 недели, пока я не сделаю новую.
Все вопросы присылайте на ящик.
::[Ø]END[Ø]::
Дизайнерское слово Ustasа
Автор: Ustas[CPM] mailto: Ustas1715@yandex.ru
"All Days I Dream About Pascal…." KoЯn
Приветствую Вас!
Возрадуйтесь, почитатели Великого Паскаля ибо скоро заработает наш ресурс на
cpm232.nm.ru, где будут выложены все выпуски, а также
исходники. И даже форум будет.
Наша команда [CPM]:
Дизайн,
верстка и корректировка>>>
Ustas[CPM]
Тоже Пишет >>> MedL[CPM]ICQ:88883515 |
© 2004 Kiev Ukraine [CPM] Group
http://subscribe.ru/
http://subscribe.ru/feedback/ |
Подписан адрес: Код этой рассылки: comp.soft.prog.pascalcpm |
Отписаться |
В избранное | ||