Уроки для начинающих программистов
Выпуск N 14
Суббота, 30 декабря 2000 г.
(кончается век...)
Ведущий рассылки Эдуард Дмитриев
Библиотека программиста (http://prog.agava.ru)
Здравствуйте, уважаемые подписчики!
Это письмо желательно читать в броузере или развернуть на весь экран, тогда легче ориентироваться и приятнее читать!

 *****  Новогодний выпуск  ***** 

В этом выпуске:
  1. HTML. JAVA Script: Праздничный снегопад.
  2. Паскаль. Модули. Мастерим падающие снежинки.
  3. Ваши вопросы. Расширенный раздел.

С НОВЫМ ГОДОМ!

Здравствуйте, уважаемые друзья, подписчики рассылки для начинающих программистов! Я рад поздравить вас с Новым годом, с новым веком, в конце концов с НОВЫМ ТЫСЯЧЕЛЕТИЕМ! Желаю вам - всем и каждому в отдельности - радости, новых и интересных начинаний, успехов во всем, в том числе и в нелегком труде программиста. Пусть сбудуться все ваши мечты и планы, пусть вдохновение и стремление к активной деятельности никогда не покидает вас - ибо это и есть двигатель жизни. Живите хорошо и поменьше вам проблем в Новом году!

Огромное спасибо всем, кто поздравил меня с Новым Годом и с прошедшим Днем рождения (22 числа). Отдельное спасибо Владе из города Ташкента, ее подарок понравился мне больше всех. Кстати, я советую и вам на него посмотреть, поверьте, он заслуживает вашего внимания. Находиться поздравление по адресу: http://mylenelee.narod.ru/ed.htm.


Дорогая Влада! Поздравляю вас еще раз с Новым годом и желаю всяческих благ и успехов! Спасибо вам! Надеюсь, мы продолжим наше общение на протяжении нового века.

Ну а на сайте рассылки "Библиотека программиста" - http://prog.agava.ru как и полагается, праздничная обстановка. Главная страница встретит вас обновленным дизайном, более подчеркивающим тематические блоки сайта и... новогодним снегопадом. Да-да, именно снегопадом. Кроме того, в этом праздничном выпуске я научу вас, как самим сделать такое, ну а для начала советую посмотреть на виртуальный снежок, возможно это добавит праздничного настроения.
Вообще, рассылка сегодня сформировалась достаточно необычная. В этом выпуске я буду отвечать на ваши вопросы, самые злободневные и часто задаваемые - я специально отбирал их для этого выпуска. Кроме того, у нас с вами будет две программы - обе новогодние и праздничные.

О ПЛАНАХ

Друзья! В новом году у меня достаточно много планов насчет рассылки, сайта и проекта "Клуб начинающих программистов". Для начала скажу, что в ближайшие дни после праздников я разошлю специальное письмо всем, кто когда либо выразил желание принять участие в создании КНП. (Вы еще можете присоединиться - ed1@mailru.com?subject=knp - в теме "knp"). Пусть даже вы писали мне в сентябре и не получили от меня ответа - все равно я постараюсь отослать письмо и вам. Тут еще дело в том, что у меня довольно долго отсутсвовал один из винчестеров и только на этой неделе мне удалось восстановить старый архив электронной почты.
Думаю, в новом году КНП всеже заработает. Подробнее о его создании я буду рассказывать в письме-приложении, если есть желание - пишите мне с темой "knp".

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

На сайте рассылки (http://prog.agava.ru), думаю, тоже произойдут некоторые изменения. В ближайшее время должен будет открыться раздел "Документация", где я постараюсь помещать полезные статьи и "Примеры кода" - раздел с примерами более продвинутых программ, написанных вами.

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

В общем, будем стараться развиваться! Присоединяйтесь!

  Новым подписчикам

Если Вы недавно подписались и Вам что-то непонятно, пожалуйста, перед тем, как спрашивать у меня, просмотрите предыдущие выпуски рассылки. Возможно, там есть ответы на ваш вопрос.
Архив рассылки можно взять на моем сайте "Библиотека программиста" - http://prog.agava.ru/.
Также там можно скачать программное обеспечение, необходимое нам для работы на сегодняшний день.
Буду особо благодарен, если Вы оставите свое мнение о рассылке на сайте и примете участие в форуме.

 

1. HTML. JAVA Script: Праздничный снегопад.

Сегодня я хочу представить Вашему вниманию небольшую программу для HTML документа, написанную на JAVA Script. Она очень инетересно работает, просто устанавливается и отлично выглядит. Программа эта заставляет сыпаться снежинки на Вашей страничке.
Работу этого скрипта смотрите на сайте http://prog.agava.ru. При этом в качестве снежинки используется рисунок - snow.gif, размером 71 байт.
Итак, ниже приведен код JAVA скрипта, просто вставьте его в документ после тэга <BODY>.



<script language="JavaScript1.2">

<!-- Begin

var no = 15;

var speed = 20;

var snowflake = "http://prog.agava.ru/snow.gif";



var ns4up = (document.layers) ? 1 : 0;

var ie4up = (document.all) ? 1 : 0;

var dx, xp, yp;

var am, stx, sty;

var i, doc_width = 640, doc_height = 480;

if (ns4up) {

doc_width = self.innerWidth;

doc_height = self.innerHeight;

} else if (ie4up){

doc_width  = document.body.clientWidth;

doc_height = document.body.clientHeight;

}

dx = new Array();

xp = new Array();

yp = new Array();

am = new Array();

stx = new Array();

sty = new Array();

for (i = 0; i < no; ++ i) {

dx[i] = 0;

xp[i] = Math.random()*(doc_width-100);

yp[i] = Math.random()*doc_height;

am[i] = Math.random()*40;

stx[i] = 0.08 + Math.random()/10;

sty[i] = 0.9 + Math.random();

if (ns4up) {

if (i == 0) {

document.write("<layer name=\"dot1"+ i +"\" left=\"15\" ");

document.write("top=\"15\" visibility=\"show\"><img src=\"");

document.write(snowflake + "\" border=\"0\"></layer>");

} else {

document.write("<layer name=\"dot1"+ i +"\" left=\"15\" ");

document.write("top=\"15\" visibility=\"show\"><img src=\"");

document.write(snowflake + "\" border=\"0\"></layer>");

}

} else if (ie4up) {

if (i == 0) {

document.write("<div id=\"dot1"+ i +"\" style=\"POSITION: ");

document.write("absolute; Z-INDEX: "+ i +"; VISIBILITY: ");

document.write("visible; TOP: 15px; LEFT: 15px;\"><img src=\"");

document.write(snowflake + "\" border=\"0\"></div>");

} else {

document.write("<div id=\"dot1"+ i +"\" style=\"POSITION: ");

document.write("absolute; Z-INDEX: "+ i +"; VISIBILITY: ");

document.write("visible; TOP: 15px; LEFT: 15px;\"><img src=\"");

document.write(snowflake + "\" border=\"0\"></div>");

      }

   }

}

function snowNS() {

for (i = 0; i < no; ++ i) {

yp[i] += sty[i];

if (yp[i] > doc_height-10) {

xp[i] = Math.random()*(doc_width-am[i]-10);

yp[i] = 0;

stx[i] = 0.08 + Math.random()/10;

sty[i] = 0.9 + Math.random();

doc_width = self.innerWidth;

doc_height = self.innerHeight;

}

dx[i] += stx[i];

document.layers["dot1"+i].top = yp[i];

document.layers["dot1"+i].left = xp[i] + am[i]*Math.sin(dx[i]+30);

}

setTimeout("snowNS()", speed);

}

function snowIE() {

for (i = 0; i < no; ++ i) {

yp[i] += sty[i];

if (yp[i] > doc_height-10) {

xp[i] = Math.random()*(doc_width-am[i]-10);

yp[i] = 0;

stx[i] = 0.08 + Math.random()/10;

sty[i] = 0.9 + Math.random();

doc_width = document.body.clientWidth;

doc_height = document.body.clientHeight;

}

dx[i] += stx[i];

document.all["dot1"+i].style.pixelTop = yp[i];

document.all["dot1"+i].style.pixelLeft = xp[i] + am[i]*Math.sin(dx[i]+30);

}

setTimeout("snowIE()", speed);

}

if (ns4up) {

snowNS();

} else if (ie4up) {

snowIE();

}

// End -->

</script>

ї  http://www.911.ru/

Вот так вот, в честь праздника!

 

2. Паскаль. Модули. Мастерим падающие снежинки.

Уважаемые друзья!
В прошлый выпуск вкралась ошибка (большое спасибо тем, кто ее заметил и написал мне об этом). Ошибся я при описании алгоритма получения отрицательных случайных чисел, перепутав диапазон. Конечно, этот вариант не правильный:

A := Random(51)-100;    {Числа от -50 до 50}

Правильным будет следующий вариант:

A := Random(101)-50;    {Числа от -50 до 50}


Ну а сегодня я расскажу вам о новой возможности Паскаля, а именно о использовании модулей. На примере использования модуля CRT мы с вами разберем программу, присланную одним из подписчиков - Андреем, за что ему огромное спасибо. Программа демонстрирует падающие снежинки.

  Модули

Модули - это отдельные файлы, содержащие дополнительные процедуры. Дело в том, что сам язык Паскаль имеет довольно ограниченное количество процедур и функций, они не позволяют производить некоторые дейсвтия. Для этого и существуют модули - они содержат в себе действия, расширяющие язык. При этом все процедуры в модулях собраны по тематическим группам. Например, модуль Graph содержит функции работы с графикой - построение линий, окружностей, многоугольников, дуг, рисование точек и т.д. Модуль DOS - позволяет обращаться к системным средствам MS-DOS, таким как чтение/удаление/создание каталогов, обращение к самой системе. Модуль CRT - позволяет обращаться к средствам консоли (клавиатура+экран): перемещать курсор в любое положение, очищать экран, менять цвет букв и фона, читать и опрашивать клавиатуру (в чем разница объясню позже), создавать текстовые окна и мн. другое.
Сегодня мы как раз и рассмотрим этот модуль. Надо сказать, что существует достаточное их количество, эту информацию мы постараемся постепенно освоить.

  Использование модулей

Сами модули храняться во внешних файлах, которые имеют расширение ".tpu" - Turbo Pascal UNIT (англ. "Модуль турбо паскаля"). Однако не всегда этот файл может существовать. К примеру, использование модуля Graph требует наличия файла graph.tpu, а вот использование модуля Crt обходиться и без файла crt.tpu. Почему, спросите вы? Дело в том, что процедуры этого модуля находятся в т.н. "Системном модуле", иначе говоря в файле "turbo.tpl". Этот файл содержит в себе все внутренние функции Турбо Паскаля и некоторых его модулей. Теперь понимаете, почему у вас не работал один файл "turbo.exe"?

Сегодня мы и займемся модулем CRT. Скажу сразу, что он содержит довольно большое количество процедур и функций, сегодня мы пройдем только основные, требующиеся нам для написания нашей новогодней программы. Да и выпуск как-никак праздничный, поэтому я постараюсь быть краток :))

Итак, чтобы работал модуль Crt и вы могли использовать его функции и процедуры, не нужно никаких дополнительных программных средств. Если вы пользуетесь дистрибутивом, который скачали с моего сайта (файлы turbo.exe, turbo.tpl, tubo.tph), то вам его вполне хватит! Я ведь уже упоминал о том, что весь Crt находиться в turbo.tpl.

Подключение модулей к программе происходит с помощью служебного слова uses, после которого указывается имя модуля. Причем uses обязательно должно быть в самом начале программы, но после слова Program. Вот пример подключения Crt:

Program UsesCRT;

uses Crt;

begin
.
.
.
end.

Теперь мы можем использовать процедуры из этого модуля. Далее я представлю программу, реализующую это, но сначала опишу новые процедуры из модуля CRT, которые будут в ней использоваться. Не забывайте выписывать их на будмагу или оформлять в отдельный файл. Так будет проще их запомнить. (Чуть-чуть позже я выложу на сайте полные списки процедур и функций большинства модулей с описаниями и примерами использования).
Да, кстати - обратите внимание на переводы названий процедур. Меня часто просят делать это из-за проблем с английским. Чтож, думаю это не лишнее.

1: Процедура ClrScr, модуль: CRT. (сокр. от англ. Clear Screen - очистка экрана).
Эта продедура очищает экран. Если вы знакомы с бейсиком, то знаете процедуру CLS. Аналогичная операция есть и в операционной системе MS-DOS - также называется CLS. ClrScr делает тоже самое.

2: Процедура GotoXY(X, Y: Byte;), модуль: CRT.
Эта продедура осуществляет переход на указанную переменными X и Y позицию экрана. При этом номер строки - это Y, а номер позиции в строке (короче, номер символа) - это X. Обратите внимание, что обычно экран имеет 25 строк по 80 символов в каждой. То есть максимально можно сделать следующее:

GotoXY(80,25);

И еще: смотрите пример использовая этой процедуры не только в программе "Снежинки", но и в раделе "Вопросы-ответы". Там есть интересный пример использования.

3: Процедура Delay(A: Word;), модуль: CRT. (анг. "Задержка");
Эта процедура выполняет задержку программы на указанное количество миллисекунд. Указывается оно параметров A, который, как видите, не может быть отрицательным. Используется эта процедра при необходимости замедлить выполнение программы - например, в сегодняшней программе "Снежинки" она тормозит сам ход снегопада - без ее использования все выпонялось бы слишком быстро.
4: Функция ReadKey: Char;, модуль: CRT.
Эта функция возвращает от своей работы последнюю нажатую клавишу. Очень похоже на работу Readln, только не ждет нажатия <Enter> и завершается сразу же при нажатии клавиши. При этом в переменную Char, к которой присваивается эта функция, заноситься введенный символ. Применение см. в разделе "Вопросы-ответы".

Ну и последняя процедура (точнее, функция) из модуля CRT, которая нам сегодня понадобиться:

5: Фукнция KeyPressed: Boolean;, модуль: CRT.
Эта функция возвращает TRUE если была нажата клавиша. Помните, я выше говорил про разнацу между "чтением" клавиатуры и "опрос" клавиатуры. Вот здесь как раз и используется эта разница: KeyPressed - это опрос клавиатуры. Readln - это чтение. (В модуле Crt также есть похожая функция - ReadKey). Разница здесь в том, что при чтении клавиатуры программа ждет, пока с нее не будут введены данные. При опросе нет ожидания и если клавиша сразу не была нажата, то программа продолжает свою работу. Получше вы сможете разобраться когда будете использовать эту функцию.

Ну и завершающий этап перед самим текстом программы - это новый раздел - const. В нем описываются константы, используемые в программе. Далее все понятно на наглядном примере. Помните, что так можно описывать и строку и символ и даже массив:

const
S='Here is string.'; { Константа - строка }
A: Array[1..5] of Char = ('a','b','c','d','e'); { Массив }

(в фигурных скобках указаны комментарии)

Итак, сегодня это все, что нам понадобиться. Пишем программу:



{ СHЕЖИHКИ }

uses crt;

    const n=79;

 Var

       x:array[1..n] of byte;

       i,k:byte;       c:char;

  Begin

      clrscr;

      for i:=1 to n do

      begin

         x[i]:=0;

      end;

      repeat

         k:=random(80);

         if x[k]=0 then x[k]:=1;

         for i:=1 to n do

         begin

           if x[i]>0 then

           begin

             gotoxy(i,x[i]);

             write(' ');

             x[i]:=x[i]+1;

             gotoxy(i,x[i]);

             write('*');

             if x[i]>23 then x[i]:=0;

          end;

        end;

        delay(100);

      until keypressed;

end.

При выполнии этой программы обратите внимание на Delay, чтобы добиться лучшего эффекта, установите его соответсвующим образом, в зависимости от вашего компьютера. К примеру, на моем компьютере (Pentium III 800) это дело работает только с параметром Delay(2000). Меньше - слишком быстро. Кроме того, автор программы также рекомендует проделать над ней следующее:
  1. усложнить задачу можно подсчетом опавших снежинок в каждом столбце, если наглядно то получить сугробы!
  2. снежинки падают под углом, в одну сторону, две стороны <= и =>

Что и будет вам сегодня новогодним заданием! Решайте!

 

3. Ваши вопросы. Расширенный раздел.

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

Вопрос 1. Можно ли в Паскале специально на некоторое время задерживать действия, т.е. производить действия через какой-либо заданный отрезок времени? (например: произвести какое-нибудь действие, а только через 3 секунды произвести другое)

Да, для этого используйте вышеописанную процедуру Delay из модуля Crt.

Вопрос 2. В выпуске 11 от 14 ноября 2000 г. предложена программка печатающая цикл из вещественных чисел от 1.00 до 1.90 с шагом 0.1. В разделе VAR Вы предлагаете переменным A и Step задать вещественный тип Single, я попробовал выдаёт ошибку: Error 116: Must be in 8087 mode to compile this. Попробовал использовать другие типы Double, Extended, Comp, результат тот-же, получилось нормально только с типом Real, я думал вначале что может название типа не так записываю, но тогда должен был выдать Error 3: Unknown identifier. Как это было пару раз раньше (написал bate, вместо byte). Да, у меня стоит полный Pascal 7.1 если конечно это имеет какое-то значение.

Нет, то что у Вас стоит Pascal 7.1 значения не имеет. Тут дело в том, что при вычислениях чисел некоторых вещественных типов используется сопроцессор. Сопроцессор (FPU) это - дополнение к Вашему центральному процессору (CPU), он берет на себя часть математических вычислений (в том числе вещественных чисел - с плавающей точкой), снижая нагрузку на CPU.
В Паскале, чтобы использовать таковой необходимо включить соответсвующую опцию: меню Options, пункт Compiler..., далее в разделе Numeric Processing поставьте отметьте (пробелом) пункт 8087/80287.

Вопрос 3. Может ли Паскаль считывать данные до нажатия "Ввода" (Например, как в Windows: нажмите Esc для отмены)?

Да, конечно можно. Для этого используйте функцию ReadKey: Char из модуля Crt (см. выше), которая читает последний введенный символ. Создайте цикл с проверкой на необходимую клавишу и все! Вот пример чтения строки до нажатия Esc (аналог Readln, только с Esc):



Program N1;

uses Crt;



var

  C: Char;

  S: String;



begin

  Write('Введите строку (Esc - конец ввода): ');

  Repeat

    C := ReadKey;

    Write(C);

    if S <> #27 then S := S + C;

  Until C = #27;

  Writeln;

  Write('Вы ввели строку: ', S);

  Readln;

end.

Комментарии:
Во-первых, обратите внимание на символ #. Этим символом указываются специальные клавиши, к примеру Esc - #27, Enter - #13 и т.д. Более подробную таблицу я приведу в дальнейшем на сайте.
Далее - я вывожу прочитанную переменную на экран. Зачем? Да потому, что ReadKey не выводит прочитанный символ на экран, только возвращает его программе.
И последнее - до того, как дополнить строку введенным символом, я проверяю его на #27 (Esc). Делаю это затем, чтобы сам символ #27 не записывался в строку. Думаю, вы и сами уже догадались.

Вопрос 4. Можно ли сделать ввод данных скрытым звёздочками (***), например, как при вводе пароля? Есть ли в Паскале функция, с помощью которой внутренний динамик может "бипнуть" (Примерно, как при загрузке компьютера)?

Думаю, я уже ответил на этот вопрос в предыдущем примере. ReadKey - не выводит символы на экран. Можно вместо Write(C) поставить Write("*");

Вопрос 5. Есть ли в Паскале функция, с помощью которой внутренний динамик может "бипнуть" (Примерно, как при загрузке компьютера)?

Да, есть. Для этого в модуле CRT существует две взаимосвязанные процедуры:
  1. Sound(Hz: Word);
  2. NoSound;
Sound(Hz: Word) - вызывает звук, подаваемый через системный динамик, с указанной частотой в Герцах. Звук будет верещать пока не будет вызвана процедура NoSound.

Вопрос 6. Скоро ли мы начнем работу с файлами?

Да, это произойдет в ближайших выпусках. В зависимости от количества вопросов - это будет либо следующий выпуск, либо через один.

Ну вот и все на сегодня. Надеюсь, этот Новогодний выпуск получился интересным и полезным для вас, уважаемые друзья!

Поздравляю вас еще раз с Новым Годом, удачи!


На этом прощаюсь, увидимся в следующем тысячелетии!

Назад

Hosted by uCoz