© 2006 Рудюк С.А.
Компания НеРуСофт
Напишем первое приложение на Lazarus. Это приложение будет выводить окно с надписью большими буквами "Добро пожаловать !".
Для этого, активизируем нашу форму Form1. Щелкнем на компоненте TLabel.
После этого щёлкнем на форме для добавления объекта.
На форме, появится компонента с надписью label1. Теперь изменим надпись на данной компоненте. Для этого, перейдём на инспектор объектов и на закладке Properties найдём свойство Font (шрифт). Щелкнем на кнопке в данном свойтве.
На экране выведется окно с запросом шрифта.
Выберите шрифт, укажите размер по больше, а так же начертание – жирный. После этого нажмите Ok.
Щёлкнем на объекте Label и с помощью узелков увеличим нашу компоненту.
После этого, в инспекторе объектов найдём свойство Caption и в поле ввода свойства введём "Добро пожаловать!" и нажмём Enter для фиксации изменения.
Для того, чтоб выполнить приложение нажмите F9 или кнопку
.
Вот и готово Ваше первое приложение. Такое же приложение Вы можете найти на компакте в каталоге Prog1.
В этой главе мы рассмотрим среду разработки Lazarus, а так же основные термины, которые будем применять дальнейшем в книге. Если Вы уже знакомы со средствами разработки Borland и владеете терминологией, тогда можете пропустить данную главу.
При первой загрузке среда FreePascal выглядит так:
Это главное окно. В нём Вы можете управлять процессом разработки приложения. В данном окне предусморены команды управления файлами, компиляцией, редактированием, окнами и т.д.
Окно состоит из 3-х частей:
Слева, в среде разработки Вы видите инспектор объектов. Верхняя часть у него показывает иерархию объектов, а снизу, расположены три закладки: Properties – свойства объекта, Events – события, Favorites – избранные свойства и методы.
Назначение инспектора объекта – это просмотр всех свойств и методов объектов.
На закладке Properties перечислены все свойства выбранного объекта.
На закладке Events перечислюються все методы для объекта.
С виду, инспектор объектов по сравнению с Delphi кажется слишком простым, но при дальнейшем изучении, оказывается у него есть такие возможности, которых отсутствуют Delphi. И надо отдать должное разработчикам Lazarus, что такие возможности ускоряют разработку приложения и делают болем прозрачной систему программирования.
По центру окна Вы видите редактор исходного текста.
Этот редактор обладает большими возможностями по редактированию текстов, а так же возможностями подсветки синтаксиса, причём не только Pascal и SQL семантики, но и других. Возможности редактора текстов мы опишем позже, когда будем рассказывать о настройке среды разработки.
В данном разделе рассмотрим основные правила и семантику языка Pascal. Если Вы программировали на Delphi или Turbo Pascal, тогда можете пропустить данный раздел.
Алфавит – это совокупность допустимых в языке символов или групп символов, рассматриваемых как единое целое. Алфавит языка Object Pascal состоит из букв, цифр, специальных символов и неиспользуемых символов. [7]
К буквам относятся большие и малые буквы латинского алфавита – от A до Z и от a до z. При этом Object Pascal не различает одноименные большие и малые буквы, если только они не входят в символьное или строковое выражение. Буквой является так же знак подчеркивания. [7]
К цифрам относятся арабские цифры от 0 до 9 и шестнадцатиричные цифры. Используя шестнадцатиричные цифры можно записать шестнадцетиричное число. Чтобы отличить десятиричное число от шестнадцатиричного, перед последним ставят знак доллара $. Диапазон шестнадцетиричных чисел – от $00000000 до $FFFFFFFF.[7]
Специальные символы можно условно разделить на разделители, знаки пунктуации, знаки операций и зарезервированные слова.
Разделители используются для отделения друг от друга идентификаторов, чисел и т.д. В качестве разделителей можно использовать:
Несколько подряд идущих пробелов считаются одним пробелом. Управляющие символы, к числу которых относится, например символ возврата каретки, генерируемый нажатием клавиши Enter, Object Pascal также интерпретирует как пробелы.
Комментариями называется любая последовательность символов заключенная в скобки { комментарий } или (* комментарий *). Такой комментарий может занимать любое количество строк и во время выполнения программы игнорируется. Основное название комментария – пояснения по тексту программы.
В Pascal так же используется комментарий вида: // Комментарий. Такой комментарий комментирует весь текст, который идёт после комментария и распространяется только на текущую строку.
Не следует путать комментарии в фигурных скобках и директивы компилятора. Директивы компилятора начинаются с пары символов {$, которые рассматриваются как одно целое.[7]
К знакам пунктуации относятся:
( ) (* *) [ ] (. .) { } " , . : ; // := .. ^ @ $ # .
Знаками операций являються:
+ - * / = <> <= >=
Зарезервированными словами в ObjectPascal являются следующие слова:
and array as asm begin case class const constructor destructor dispinterface div do |
downto else end except exports file finalization finally for function goto if implementation |
in inherited initialization inline interface is label library mod nil not object of |
or out packed procedure program property raise record repeat resourcestring set shl shr |
string then threadvar to try type unit until uses var while with xor |
Приведённые слова используются в программе только по своемому прямому назначению, и не могут быть использованы в качестве идентификаторов.[7]
Неиспользуемые символы, к которым в частности относятся буквы русского алфавита, могут быть использованы в комментариях, а также символьных и строковых константах.[7]
Идентификаторы (имена) – используются для обозначения констант, типов, переменных, процедур, функций, классов, модулей программ и т.д. Идентификаторы состоят из букв и цифр и должны начинаться с буквы. Длина идентификатора может быть произвольной, но значащими являются только первые 64 символа. Поскольку знак подчёркивания "_" относится к буквам, он может входить в идентификатор. Специальные символы и неиспользуемые символы не могут входить в состав идентификаторов. В частности, зарезервированные слова (program, begin, end и т.д.) нельзя использовать в качестве идентификаторов. [7]
Допустимые имена:
name_23 x y name_and_fam CountryName
Недопустимые имена:
58_ok – начинается с цифры;
begin – зарезервированное слово;
начало_23 – содержит русские буквы;
text.3 – содержит специальный символ;
p 3 – содержит пробел;
Кроме зарезервированных слов в Object Pascal имеются так называемые стандартные имена. К ним относятся имена стандартных функций, например: sin, cos, exp, ln и т.д. Стандартными именами являются также имена стандартных директив, которые используются для объявлений в программе, например: override, virtual, private, protected и т.д. В отличие от зарезервированных слов стандартное имя можно переопределить, правда, при некоторых ограничениях. Возможность эта скорее теоретическая, и на практике рекомендуется использовать свои оригинальные имена.[7]
Простейшее приложение на языке Object Pascal состоит из заголовка и так называемого блока. Блок состоит из разделов:
Раздел операторов должен быть заключен в операторные скобки begin … end. В нём указывается последовательность действий, которую должен выполнить компьютер. Все остальные разделы носят описательный характер.[7]
В Object Pascal любой раздел, кроме последнего, может отсутствовать. И наоборот – любой описательный раздел может встречаться несколько раз, при этом порядок следования разделов может быть произвольным. Выбирая порядок расположения описательных разделов, следует руководствоваться правилом: все используемые типы, константы, переменные, функции, процедуры должны быть объявлены или описаны до их первого использования. [7]
Разделителями между разделами и операторами служит точка с запятой. В конце приложения должна стоять точка.
В любом месте приложения, где допускается присутствие разделителя, например – пробела, можно вставить комментарий. Комментарий не изменяет смысла приложения и предназначен для пояснения.[7]
Пример. Составим консольную программу запроса имени пользователя и пароля. Если введено имя пользователя SYSDBA и пароль masterkey, тогда на пишем "Hello!", если нет, тогда выводим "Error password or username." и повторяем аутенификацию повторно.
program Console;
{$mode objfpc}{$H+}
{$AppType CONSOLE} // Если мы указываем эту директиву, тогда компилятор будет знать, что это
// консольное приложение
uses
SysUtils; // Библиотека с функцией trim
var UserName: String; // Переменная для имени пользователя
Password: String; // Переменная для пароля
label l1; // Метка для возврата на начало аутенификации
procedure Authenification;
// Процедура для ввода имени пользователя и пароля
Begin
Write('User Name: ');
readln(UserName);
Write('Password: ');
readln(Password);
End;
function IsOk: Boolean;
// Проверяем известен ли нам пароль и имя пользователя
// Если имя пользователя SYSDBA и пароль masterkey, тогда возвращаем True
// иначе - False
Begin
result:=(trim(UserName)='SYSDBA')and(trim(Password)='masterkey');
End;
begin
l1: Authenification; // Аутенификация пользователя
// Если пароль прошел, тогда выводим надпись Hellom,
// если нет, тогда сообщаем о ошибочном пароле и требуем повторить ввод.
if IsOk then
begin
Writeln('Hello!'); // Выводим на экран сообщение
readln; // Ждём нажатия любой кнопки
end
else
begin
WriteLn('Error password or username.'); // Выводим на экран сообщение
WriteLn('Press any key.'); // Выводим на экран сообщение
readln; // Ждем нажатия любой кнопки
goto l1; // Переходим на повторный ввод пароля
end;
end.
Программу Вы можете найти на компакте в каталоге ConsoleApp.
Примечание: Если Вы всё время будете вводить не верный пароль или имя пользователя, тогда программа будет требовать ввод до бесконечности. Чтоб прервать выполнение программы из Lazarus не обходимо из среды разработки нажать комбинацию клавиш Ctrl+F2.
Хоть Lazarus и требует для своего выполнения графический интерфейс, тем не менее Вам никто не мешает писать консольные программы. Такие программы будут выполняться в текстовом режиме и не требовать графическую среду. Таким образом, Вы можете писать утилиты для *nix систем, которые будут выполнять огромную работу и управление которыми можно будет делать с помощью терминального соединения в текстовом режиме. Для выполнения таких утилит не нужно ставить среду выполнения (как это происходит в PHP или Java), а Вего лиш переписати саму утилиту на сервер.
Результат выполнения программы:
User Name: Test
Password: ddd
Error password or username.
Press any key.
User Name: SYSDBA
Password: masterkey
Hello!
Заголовок программы начинается со служебного слова program, после котрого следует имя программы – правильный идентификатор.[7]
Раздел меток начинается словом label, за которым следует список меток. Метка представляет собой правильный идентификатор или целое число без знака. Метки позволяют пометить любой оператор, чтобы можно было передать управление из любого места программы.[7]
Раздел констант начинается словом const, за которым идут инструкции вида [7]:
<имя константы> = <значение>
Раздел описания типов начинается служебным словом type, за которым идут конструкции вида
<имя типа> = <описание>
позволяющее программисту создавать собственные типы.
Раздел описания переменных начинается служебным словом var. здесь должны быть указаны все переменные, используемые в разделе операторов программы, а также их тип.[7] В частности, в нашей программе мы писали: var UserName: String; - это объявлялась переменная UserName со строковым типом данных (string).
Раздел описания процедур и функций не выделяется специальным служебным словом, поскольку каждая программа имеет свой заголовок. В нашем примере используются две под-программы: одна функция (IsOk) и одна процедура (Authenification). Процедуры объявляются зарезервированным словом procedure, а функции – function. Каждая процедура и функция могут иметь структуру, подобную основной программе, в том числе использовать собственные, локальные переменные, функции и процедуры.[7]
Раздел операторов начинается служебным словом begin и заканчивается словом end, после которого ставится точка – признак конца программы. Между этими ключевыми словами размещаются операторы языка Object Pascal, которые необходимо выполнить для решения задачи.[7]
Типы данных в Object Pascal можно разделить на стандартные и определяемые программистом. К стандартным типам относятя: целые, действиетельные, символы, строки, указатели, логические, variant и т.п. [7]
Программист может определять свои типы данных. Для этого, предназначено зарезервированное слово type. Так же можно определять свои типы данных непосредственно в разделе переменных var.[7]
Пример типов, определённых пользователем:
type
TMyObject = class(TObject) // Новый тип класса
private
FText: String;
public
InfoID: Integer;
published
property Text: String read FText write FText;
end;
TMyRec = record // Новый тип записей
ID: integer;
Name: String;
end;
TColorAvto = (AutoRed, AutoWhite, AutoBlue); // Перечисляемый тип
var MyObj: TMyObject; // Переменная типа TMyObject
Rec1, Rec2: TMyRec; // Две переменные типа запись
Auto: TColorAvto; // Переменная типа TColorAuto
colors: (Blue, White, Red); // Переменная перечислимого типа.
// Объявление типа происходит
// прямо из раздела переменных
arr: array of integer; // массив переменных типа integer
Стандартные типы не нуждаются в дополнительном описании их можно сразу применять в программе.
Стандартные типы можно классифицировать [7]:
В Object Pascal есть два типа констант: обычные и именованные.
Под обычными, подразумеваются числа, строки, логиские значения, символы. Числовые константы могут иметь положительное или отрицательное значение. [7]
Примеры не именованных конастант:
568 – числовая константа;
332,23 – числовая константа с дробной частью;
893,77e2 – числовая константа с дробной частью (e2 – соответствует 10 в степени 2), т.е. это идентично с 8,9377.
'Привет' – строковая константа.
'A' – символьная константа.
Обратите внимание, что строковые или символьные константы заключаются в одинарные кавычки. Наряду с одинарными кавычками можно применять так же двойные.
Например:
"Ура" – строковая константа.
"Прив'язати" – строковая константа. Одинарная кавычка считается частью строковой константы, т.к. находится внутри двойных кавычек.
Символ так же можно указать с помощью его кода. Данный код можно определить из таблицы символов.
Для того, чтоб просмотреть таблицу символов в Windows Вы можете щелкнуть на кнопке Пуск, выбрать меню Все программы, далее – Стандартные, входите в Служебные, и запускаете программу Таблица символов. (Далее в книге для краткости мы будем писать: Пуск -> Все программы -> Стандартные -> Служебные > Таблица символов).
Внизу Вы видите код символа в шестнадцерисном виде.
С помощью символа # можно указать код символа с помощью шестнадцетиричного кода (для этих же целей можно воспользоваться функцией chr(x)).
Для того, чтобы перевести десятичное значение в шестнадцетиричное, необходимо помнить, что символы латинского алфавита, начиная с A по F соответствуют цифрам с 10 по 15.
Таким образом, цифра 4С, символа, изображенного на картинке, соответствует 4*16+12(символ C)=76. Таким образом, в программе символ L вы можете задать двумя способами:
Последовательность символов 'ABCD' эквивалентна #65#66#67#68.
Если Вам необходимо много цифр преобразовывать между шестнадцетиричной, десятиричной, восмиричной и двоичной системами, тогда Вы можете воспользоваться стандартным калькулятором. В Windows, калькулятор Вы можете вызвать с помощью команды Пуск -> Все программы -> Стандартные -> Калькулятор. После этого, необходимо переключить калькулятор в инженерный режим (команда Вид -> Инженерный).
Выберите систему исчисления: Hex (шестнадцетиричная), Dec (десятиричная), Oct (восьмиричная), Bin (двоичная). Введите число. После этого с помощью переключателя единиц измерений Вы можете посмотреть значения данного числа в различных единицах измерения.
Логические константы имеют два значения: False (ложь), True (истина).
Именованная константа объявляется с помощью зарезервированного слова const и отличается от обычной константы тем, что имее название. Это полезно, когда Вы применяете одно и то же значение в различных местах программы. В этом случае, хоть и применяется константа в различных местах программы, но изменить её значение хватит только в одном месте – там где она определена.
Пример задания констант:
const
s1_string='1C'; // Строковая константа со значением 1C
NDS=20; // Числовая константа со значением 20
Pi=3.14; // Числовая константа с плавающей запятой
No=False; // Логическая константа
В константном выражении могут использоваться другие константы, операции и некоторые стандартные функции. [7]
Например:
const
summa_naloga=1500*0.2; // Применяется операция умножения
SummaAbs=abs(1500); // Используется стандартная функция
FullName='Sergey'+' '+'Rudjuk'; // Используется объединение строк
Отметим, что вычисление констант происходит в момент компиляции. Таким образом, в момент выполнения используются заранее вычисленные значения, благодаря чему, программа работает быстрее.
Константы нельзя изменять во время выполнения. Но, есть специальный тип констант – типизированные константы. Такие константы можно изменять во время выполнения. [7]
Пример типизированных констант:
const
NDS: integer = 20; // НДС
SummaNDS: Currency = 1500*0.2; // Сумма НДС
Переменные – это данные программы, которые в процессе её выполнения могут менять своё значение.
В Pascal каждая переменная, которая используется внутри текста должна быть предварительно объявлена в разделе переменных.[7]
В качестве имени может быть использоваться любой правильный идентификатор. Компилятор не различает большие и маленькие буквы, поэтому переменные username и UserName – идентичны.
Пример объявления переменных:
var
NDS: integer;
SummaNDS: Currency;
str1, str2, str3: String;
str4: String;
Sim: Char;
is_ok: Boolean;
Переменные могут быть глобальными и локальными. Если переменная объявлена внутри процедуры или функции, тогда это локальная переменная. Она будет видна только в пределах данной процедуры или функции.
В Object Pascal различают такие операции:
Порядок выполнения операций:
Для определения порядка выполнения рекомендуется пользоваться следующими правилами [7]:
Таким образом, Вы можете управлять последовательностью выполнения операций с помощью круглых скобок.
Следует отметить, что операции могут делаться с целыми и строковыми типами. Нельзя выполнить операцию без преобразования типов между целыми (вещественными) числами и строковыми.
Рассмотрим различия трёх операций: / (деление), div (целочисленное деление), mod (остаток от деления).
При делении с помощью / результат получится вещественного типа, например:
5/2=2.5
При делении с помощью div Вы получите целое число (ту часть, которая идёт до запятой), например:
5 div 2 = 2.
При делении с помощью mod Вы получите целое число – остаток от целочисленного деления.
5 mod 2 = 1.
8 mod 3 = 2.
В Object Pascal предусмотрено большое количество процедур и функций. Рассмотрим некоторые из них.
Арифметические функции
abs(x) – абсолютное значение;
exp(x) – экспонента;
frac(x) – дробная часть аргумента: x-int(x).
pi – число пи (3.1415926535).
sqrt(x) – квадратный корень.
sqr(x) – квадрат.
round(x) – округление.
trunc(x) – отсечение дробной части вещественного числа.
int(x) – целое число.
Тригонометрические функции
cos(x) – косинус;
sin(x) – синус;
tg(x) – тангенс;
arctan(x) – арктангенс.
Операторы можно разделить на два типа простые и сложные.
Простые операторы – это операторы, не содержащие в качестве составных частей другие операторы. К простым относятся: оператор присваивания (:=), оператор безусловного перехода (goto), пустой оператор (;).[7]
К сложным операторам относятся: составной оператор, условный оператор (if), оператор выбора (case), операторы цикла (for, while, repeat) и оператор присоединения (with). [7]
Оператор присваивания предназначен для замены текущего значения переменной, на новое значение.
Например:
var strtmp: string;
begin
strtmp:='Hello!'; // Устанавливаем значение Hello
writeln(strtmp); // Выводим значение Hello
strtmp:='This is new text'; // Устанавливаем значение This is new text
writeln(strtmp); // Выводим значение Hello
end
Мы рассмотрели немного теории. Теперь приступим к практическому занятию. Создадим консольное приложение в Lazarus. Именно в консольных приложениях мы будем изучать различные аспекты программирования в Object Pascal. После того, как изучим возможности Object Pascal, перейдём к созданию графических приложений.
Откройте среду разработки.
Выполните команду File -> New.
Выберите FPCUnit Console Application и нажмите Ok.
Если у Вас было загружено другое приложение, тогда компилятор спросит сохранить его или нет:
Если хотите сохранить, тогда нажмите Yes, если нет – No (т.к. мне не нужно сохранять я отвечаю No).
После этого Lazarus спросит название приложения:
Задайте название, например TestConsole и нажмите кнопку Create unit.
Закроем форму и текст формы. Среда разработки спосит сохранить файл unit.pas,
на что вы отвечаете – Нет. Теперь у нас остался только сам файл проекта. Сразу
сохраним его на диске (сохранение информации должно быть Вашей привычкой). Для
этого нажмите кнопку
.
Укажите каталог и название pas-файла.
Примечание: рекомендуется задавать название маленькими буквами, так как в *nix системах различается регистр букв и разница в регистрах букв в этих операционных системах может приводить к проблемам. Если Вы зададите название с большими буквами, тогда могут возникнуть некоторые проблемы в *nix-системах. Кроме того, нельзя, чтоб название pas-файла, название проекта и название класса совпадало. Делайте их разными.
Укажите название для pas-файла, а так же для файла проекта.
Нажмите F9 для запуска проекта. Вы заметите, что промелькнуло черное окно консоли и сразу же скрылось.
Lazarus сразу же сгенерировал текст для консольного приложения, но в принципе нам такой текст не нужен. Откроем текст проекта Project -> View Source, укажем директиву в тексте проекта: {$AppType CONSOLE}
Вместо текста, сгенерированного Lazarus, введём:
program consple_laz;
{$mode objfpc}{$H+}
{$AppType CONSOLE}
begin
end.
Выполните приложение и Вы увидите, как промелькнёт текстовое окно.
Это совершенно пустое консольное приложение. В дальнейшем, мы часто будем им пользоваться.
В предыдущих главах мы уже сталкивались с процедурами Write и Readln. В этой главе рассмотрим данные процедуры более подробно.
Назначение процедуры Write – выводить значение. Таким образом, текст который мы передаем этой процедуре будет выводиться на экране.
Назначение процедуры Read – вводить значение в переменную из клавиатуры. Программа будет ожидать ввода из клавиатуры. Завершение ввода производится с помощью нажатия кнопки Enter.
Если процедуры Write и Read мы завершим окончанием ln, тогда после ввода или вывода информации эти процедуры будут переводить каретку курсора на следующую строку.
Следует отметить, что в процедуры Write, Read, Writeln, Readln можно передавать не один аргумент, а не ограниченное количество.
Рассмотрим примеры вывода информации на экран:
Write('Привет!'); // Выводит на экран текст Привет!
Write('Иванов ', 'Иван ', 'Иванович'); // Выводит на экран Иванов Иван Иванович
Writeln('Привет!'); // Выводит на экран Привет! и переводит курсор на следующую строку
Writeln('Иванов ', 'Иван', 'Иванович');// Выводит на экран Иванов Иван Иванович и переводит курсор на следующую строку
Примечание: К сожалению, часто в текстовом режиме не задаётся корректно таблица символов для кириллицы. Поэтому, при выводе информации на русском языке Вы можете увидеть абракадабру. Поэтому, во примерах с консольными приложениями мы выводим текст на английском языке.
Рассмотрим примеры ввода информации из клавиатуры:
read(x); // Запрашиваем ввод одного значения
readln(y); // Запрашиваем ввод одного значения с переодом каретки
read(x, y, z); // Запрашиваем ввод трёх значений
readln(x, y, z); // Запрашиваем ввод трёх значений с переводом каретки
Если выводить текст друг за другом, а так же вводить его без расстояния между элементами при большом значении создастся на экране хаос. Поэтому, Паскаль предусматривает форматированный вывод информации на экран.
Форматирование производится следующей командой:
write('Привет!':15, 'Привет!':15, 'Привет!':15 );
Цифра 10 указывает количество символов для форматирования.
При выполнении этой команды на экране мы увидим:
Привет! Привет! Привет!
Программа. Составим программу, которая будет запрашивать фамилию, имя, отчество.
Отдельной строчкой: дату рождения. Следующей строчкой: адрес проживания.
После того, как всё будет введено эта информация красиво должна быть выведена на экран.
Возьмём проект, который мы делали в предыдущей главе и напишем код. Листинг программы:
program consple_laz;
{$mode objfpc}{$H+}
{$AppType CONSOLE}
var Fam, Im, Otch: String; // Фамилия, имя и отчество
Birthday: String; // День рождения
Adress: String; // Адрес проживания
begin
writeln('Enter ','First ','Middle ','Last:'); // Выводим приглашения для ввода фамилии, имени и отчества
readln(Fam); // Ввод фамилии
readln(Im); // Ввод имени
readln(Otch); // Ввод отчества
write('Birthday: ');
readln(Birthday); // Ввод дня рождения
write('Adress: ');
readln(Adress); // Ввод дня рождения
write(''); // Вставляем пустую строку
write(''); // Вставляем пустую строку
write(''); // Вставляем пустую строку
writeln('=========== You datas ============');
writeln('First:':10, Fam); // Выводим фамилию
writeln('Middle:':10, Im); // Выводим имя
writeln('Last:':10, Otch); // Выводим отчество
writeln(''); // Вставляем пустую строку
writeln('Birthday:':10, Birthday); // Выводим день рождения
writeln('Adress:':10, Adress); // Выводим адрес
Readln;
end.
Выполнение программы:
Enter First Middle Last:
Рудюк
Сергей
Анатольевич
Birthday: 17.04.2006
Adress: г.Киев
=========== You datas ============
First:Рудюк
Middle:Сергей
Last:Анатольевич
Birthday:17.04.2006
Adress:г.Киев
На компакте, этот проект Вы можете найти в каталоге Fam.
|
Программирование для чайников.
|