Уроки для начинающих программистов
Выпуск N 9
Суббота, 14 сентября 2000 г.
Всего подписчиков - 12190
Ведущий рассылки Эдуард Дмитриев
Здравствуйте, уважаемые подписчики!
Это письмо желательно читать в броузере или развернуть на весь экран, тогда легче ориентироваться и приятнее читать!

В этом выпуске:
  1. О выпуске
  2. Уроки HTML. Внутренние ссылки
  3. Уроки программирования на Паскале
  4. Вопросы - ответы

-> C = A + B;
  • Это "-"?
    -> C = A - B;
  • Это "*"?
    -> C = A * B;
  • Вывести результат;
  • Спросить - сначала?
  • Если ответ утвердительный, то начать все сначала (переход к пункту 1);
  • Конец нашей программки.
  • Вот исходный текст, реализующий этот алгоритм:

    1. О выпуске

    Здравствуйте, уважаемые подписчики! Сразу же хочу извиниться за долгое отсутсвие выпусков (а именно около месяца), следовательно и за пробелы в нашем с вами продвижении. Причиной тому служат проблемы по работе и домашние разногласия, не получалось распределять усилия на рассылку и уделять внимание выпускам. Так же и сайт - тоже временно молчал раздел Новостей и не было даже прошлых выпусков рассылки. Зато теперь есть кое-какие интересные пополнения - как и обещал, появились ответы на домашние задания по Паскалю, заданные в прошлом выпуске. Еще надо сказать, что полностью преобразился раздел для подписчиков - сейчас все ссылки оформлены отдельным большим разделом, озаглавленным "Уроки для начинающих программистов". Теперь Вы сможете увидеть домашние задания, гостевую книгу, вопросник, программы и другое, пройдя по одной ссылке.
    Также в некотором роде решилась проблема с Турбо Паскалем - он иногда не загружался или загружался, но архив был испорчен. Такое бывает, возможно из-за загруженности сервера, а может и из-за проблем с DNS. Но это уже не столь важно, я перенес файлы Паскаля на более разгруженный и быстрый сервер, главное, он находится в России - так что теперь все должно работать гораздо лучше.
    Кстати, эта информация будет полезна новым подписчикам, которых на сегодня довольно много. Чтож, приветствую новичков! И хочу заострить ваше внимание на следующем подразделе:

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

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

      Клуб начинающих программистов

    Вообще, идея создания "Клуба начинающих программистов" это идея не однодневная, то есть такой клуб (тем более для такого количества пользователей) реализовать не просто, особенно в одиночку. Поэтому хочу провозгласить следующее: приглашаются все желающие учавствовать в создании клуба, люди, знающие Паскаль, Си, Бейсик (VB), DELPHI, HTML, PHP (определенно, среди около 12000 такие существуют), работающие с графикой, а также все, кто может интересно излагать свои идеи. Присоединяйтесь!

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

    В клубе будет существовать несколько разделов, посвященных разным темам. Делиться все будет по языкам программирования, далее по различным подходам к программированию, предпочтениям и методам реализации тех или иных особенностей. Информация будет в ON-LINE, она будет представлять собой статьи, написанные вами. Каждый желающий сможет написать статью, а также оценить существующие - что позволит другим выбирать высоко оцениваемую, а следовательно самую полезную информацию. Вот и получиться, что все будут как-бы помогать друг другу. Главное, чтобы у кого-нибудь время от времени появлялось желание написать в КНП свою статью или решение проблемы; тогда КНП действительно сможет помочь начинающим разбираться в программировании. Здесь хочу сказать, что если все сложиться удачно, то размеры клуба скоро выйдут за пределы рассылки и уже все желающие смогут им пользоваться, что будет удачным решением.
    Будут форумы на различные темы - но уже в главных разделах, то есть по конкретным языкам программирования. При наличии инициативы со стороны знающих людей появяться FAQ (или ЧаВО), где отвечать на вопросы будет один модератор.
    Вот так, кратко. Жду идей и корректив с вашей стороны.

     

    2. Уроки HTML. Внутренние ссылки

    В двух прошлых выпусках я рассказывал о гипертекстовых ссылках, которые позволяют переходить от одного документа к другому. Думаю, вы смогли оценить эту возможность - ее достоинства и простоту. Но по ходу изучения ссылок нельзя обойти стороной еще одну примечательную возможность - возможность перехода по тексту.
    Что же такое переход по тексту? Все очень просто, и если вы подписаны на рассылку в HTML формате, то сможете увидеть пример использольвания этой возможности прямо здесь, в рассылке. Для этого посмотрите на меню "В этом выпуске", видите, там есть пункты? Каждый из них является ссылкой, нажав на которую Вы перемещаться по тексту рассылки. Это очень удобно, не так ли?
    Вот этому вам сегодня и предстоит научиться - перемещаться по тексту, или иначе "внутри документа". Это совсем легкая тема, небольшая и не требующая особой практики и понимания, поэтому кроме ссылок я хочу также рассказать вам о новых тэгах, позволяющих работать с текстом. Объяснения будут скользящими, то есть я не буду подробно останавливаться на каждом из них - вы сами поймете, почему. Ведь они очень простые.

      Внутренние ссылки

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

    Имена задаются с помощью того же тэга, который используется для оформления ссылок - тэга <a>. Для этого у <a> есть специальный параметр - name. Именно с помощью него и присваивается имя, или метка. Вот пример:

    Здесь идет текст....
    <a name="text">
    Здесь идет подзаголовок, имеющий свое имя.

    Теперь место, где начинается строка "Здесь идет подзаголовок..." имеет свое имя в документе. Это имя доступно гипертекстовым ссылкам, и можно без проблем оформить такую сслыку, которая будет на это имя ссылаться. Для этого мы опишем обыкновенную конструкцию <a href>, но в качестве адреса укажем это самое имя. Ну а для того, чтобы показать броузеру, что это не название файла и не адрес Интернет, мы перед именем в обязательном порядке поставим символ #, который и выполнит эту задачу. Вот, собственно и все - привожу пример оформления таких ссылок:

    <a href="#text">Перейти к подзаголовку</a>

    Думаю, вы со мной согласитесь, что это просто. Хочу сказать, что это не очень распространенная возможность - на практике ей не приходить пользоваться очень часто. Она очень удобна для построения текста, но при создании сайта используется мало. Однако не знать эту возможность тэга <a> нельзя. Запомните ее и используйте при необходимости.

      Тэги оформления текста

    Когда я говорю "Тэги оформления текста", я имею в виду тэги вроде <b> - </b>, выделяющие текст жирным и тэги <center> - </center>, выравнивающие текст по центру. Мы изучили немного таких тэгов, их существует больше. Вот сегодня я и расскажу вам о других таких тэгах, выполняющих те или иные действия над внешним видом текста.

    Итак, первый тэг это <I>.
    Тэг <I> (латинская I (и) - иногда путают с l (эль) или вообще единицей - 1) позволяет печатать текст курсивом, то есть наклонным. I - это сокращенно от Italy, то есть итальянсткий стиль, возможность используется в большинстве текстовых редакторов.
    Тэг этот имеет завершающую пару - </I>. Все, что будет написано внутри этих тэгов и будет печататься наклонным шрифтом.

    Вот пример текста:

    Этот текст выводиться с помощью тега <I>

    А вот пример непосредственного использования тэга:

    <I>Этот текст напечатается курсивом</I>

    Следующий тэг - <U>.
    Работа этого тэга - вывод текста в подчеркнутом виде. U - это сокращение от английского underline - подчеркивание. Тэг, естественно, имеет завершающую пару - </U>. Все, что находиться между этими двумя тэгами и будет подчеркнуто.

    Пример подчеркнутого текста:

    Этот текст выводиться подчеркнутым

    Пример использования тэга <U>:

    <U>Этот текст будет подчеркнутым </U>

    Вот такие простые и полезный два тэга. На этом сегодняшний урок по HTML закончен, он был не большой и довольно простой. Однако полученные согодня знания вам все же пригодятся - умение оформлять текст является одной из главных задач вебмастера.
    Забегая вперед скажу, что в ближайшем будущем мы перейдем к основопологающей теме HTML - таблицам. Именно с их помощью и строятся меню, организуется структура гипертекста. Ну а сейчас я заканчиваю, до следующего урока!

     

    3. Уроки программирования на Паскале

    В прошлом (практическом) выпуске мы с вами закрепили тему циклов, прошли новые конструкии и попробовали кое-какие приемы программирования. Сегодня тема циклов будет продолжена и мы с вами займемся одним из оставшихся - так называемым циклом While. Этот цикл имеет свои специфические особенности использования и выполнения перед циклом For, я постараюсь их вам как можно более подробно изложить.
    Также напомню, что в прошлом выпуске я задал домашнее задание. Надеюсь, Вы его выполнили и особых проблем не возникало. Ответы, а точнее правильные решения смотрите на сайте - сравнивайте, извлекайте уроки. Кстати, если вы новый подписчик и увидели домашнее задание уже в архиве рассылки, я вам не советую сразу же нажимать на ссылку Домашние задания. Попробуйте сначала сами, чтобы потом не списывать, а сравнивать - это гораздо полезнее, поверьте.

    Продолжим циклы. Как я уже сказал, сегодня будет цикл While, его синтаксис немного позже, а пока расскажу о том, как он применяется.

    Работая с циклом FOR вы наверняка заметили, что программа повторяется всегда фиксированное количество раз - пусть даже это количество и задается в ходе выполнения программы, но изменять его в ходе выполнения цикла нельзя. Если сказано прокрутить цикл десять раз, десять раз он и прокрутиться. Наводит на мысль, что цикл For использовать удобно при подходящей ситуации - например, каких-нибудь математических расчетах или внутреннем выполнении действий. А вот если нам понадобилось внешняя работа с данными, циклически оформлеными? Это например, может быть таже программа ввода строки, которая будет читать строку, пока та не будет содержать слова "end". Мы кстати писали подобную программу, она использовала в качестве зацикливания процедуру goto, переходя на новое чтение при определенных условиях. Вы замечаете разницу? Задумайтесь - чтение строки, это ведь работа с внешними данными? Так ведь? И если это чтение происходит по кругу, то это ведь цикл? Тоже верно. Но выполнение этого цикла несколько специфичное - он работает до возникновения определенных условий (опять же со стороны внешних данных).
    Вот здесь как раз и будет удобо использовать цикл While. Особенностью этого цикла является то, что он будет выполнять свою работу до возникновения каких-либо условий, то есть сам он ничего не изменяет в переменных, он всего лишь что-либо проверяет. (Помните, цикл FOR изменяет переменную-счетчик?) В заголовке этого цикла стоит не диапазон значений, а собственная процедура проверки - вроде известной нам if...then...else, далее вы сами это увидите.
    Ну а теперь для демонстрации этого цикла давайте напишем программу, которая и будет выполнять чтение строки до того момента, пока она не будет строкой "end". Смотрите программу:

    Program N1;

    var

    S: String;

    begin

    While S <> 'end ' do
       Readln(S);

    Write('Вот и все! Вы ввели end! ');
    Readln;
    end.

    Запустите программу. Видите, она читает строки до того момента, пока введенная строка не будет равна "end"? Просто, не правда ли? Теперь внимательно посмотрите на программу. Здесь налицо, что вместо типичного диапазона значений цикла (как FOR - повторять от сих до сих) стоит процедура проверки, то есть "повторять пока". Кстати, while переводиться с английского как "пока". Теперь необходимые комментарии к изученному циклу.

    1. Для того, чтобы оформить цикл while предназначено служебное слово while.
    2. После указания этого слова идет логический диапазон цикла, то есть нужно написать, при каких условиях цикл закончиться. Это реализуется посредством известных нам знаков сравнения и их взаимоотношения с переменными.
    3. После указания условия ставиться служебное слово do.
    4. Теперь идет само тело цикла. Здесь помните, что если в теле цикла содержиться один оператор (как в первом примере), то он указывается без дополнительных выделений. Если же идет несколько операторов, то они все заключаются в конструкицю begin-end. Это очень принципиально, не забывайте про это!

    Хочу сделать немного уточнений по поводу процедуры сравнения. На самом деле это процедура может быть довольно сложной, составленной из нескольких условий. Например, так:

    Пока A < B и B > C

    Это может быть использовано и в конструкции if...then...else и в цикле while. Однако рассказывать о том, как реализуются сложные конструкции сравнения я буду в следующих выпусках, в частности, практических, где мы будем решать задачи.
    А пока нам нужно закрепить пройденный материал и написать несколько задач с использованием новых возмножностей.

    Я считаю уместным модифицировать написанные ранее программы, дабы показать более рациональные медоты из выполнения. Так для примера мы напишем калькулятор (не интерактивный, правда), в котором и используем цикл while. Давайте определимся, что же будет делать наша программа.

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

    1. Ввести А;
    2. Ввести В;
    3. Ввести знак действия;
    4. В зависимости от того, что это за знак, выполнить действие:
      1. Это "+"?
    Program Simple_Calculator;

    var

    A,B,C: Integer;
    Ch, Sign: Char;

    begin

    While UpCase(Ch) <> 'N ' do
    begin
       Write('Введите А: ');
       Readln(A);
       Write('Введите B: ');
       Readln(B);
       Write('Введите знак действия: ');
       Readln(Sign);

       If Sign='+' then C := A + B;
       If Sign='-' then C := A - B;
       If Sign='*' then C := A * B;

       Writeln('Результат: ', C);
       Write('Сначала? (Y/N): ');
       Readln(Ch);
    end;

    Write('Калькулятор завершает свою работу... ');
    Readln;
    end.

    Вот такая вот программа. Что скажете? Думаю, вы уже обратили внимание, что она не использует процедуру goto для сравнения. Все операции протекают в цикле, который оформлен в виде while и уже является полноценным циклом, в отличии от макета goto if...., который мы использовали ранее.
    Вообще, я хочу вам сказать, что goto лучше по возможности не использовать; эта процедура затрудняет чтение программы и запутывает ее логику, что в более-менее больших программах недопустимо.
    Итак, введите и запустите эту программу. Она хорошо справляется со своими обязанностями, правда? Хочу заметить, что в программе я использовал незнакомую функцию UpCase, необходимые комментарии:

    Функция UpCase - возвращает как результат своей работы переменную-символ в верхнем регистре. В качестве параметра к функции задается переменная типа Char. Если эта переменная является буквой в нижнем регистре, она превратиться в большую, заглавную букву.
    В других случаях (например, переменная Char является цифрой) ничего не произойдет.
    Это и есть вся работа функции UpCase.

    Теперь вам небольшое задание по этой программе:
    Как вы думаете, зачем я использую функцию UpCase в процедуре проверки цикла While?
    Жду ваших писем.
    *Правильный ответ напечатаю в следующем выпуске.

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

    1. Вводим число;
    2. Пока это число меньше нуля, делаем следующее:
      1. Получаем остаток от деления введенного числа на 10; Получившийся остаток и будет первым разрядом, т.е. единицами;
      2. Вычитаем получившийся остаток из имеющегося числа;
      3. Делим получившееся число на 10 без остатка
      4. Выводим его на экран;

    3. Спрашиваем, сначала?
    4. Если да, то переходим к пункту 1;
    5. Завершаем программу;

    Если сейчас не очень понятно, не расстраивайтесь. Дальше по ходу написания программы разберетесь, что к чему. Итак, программа:

    Program Get_numbers;

    var

    A, B: Integer;
    Ch: Char;

    begin

    While UpCase(Ch) <> 'N ' do
    begin
       Write('Введите число: ');
       Readln(A);

    While A > 0 do
    begin
       B := A mod 10;
       Dec(A, B);
       A := A div 10;
       Writeln('Разряд: ', B);
    end;

       Write('Сначала? (Y/N): ');
       Readln(Ch);
    end;

    Write('Конец программы... ');
    Readln;
    end.

    Посмотрите внимательно на текст этой программы. Здесь я опять использовал незнакомые слова вроде mod и div, поэтому перед тем, как рассказывать о работе программы, разъясню, что же они делают.

    Операция div - выполняет деление целых чисел (Integer, Byte, Word, LongInt - см. выпуск N4) без остатка. Работа этой операции очень проста - например, при делении числа на 10 (как в нашем случае) результат не всегда получится целым (123 div 10) и не может храниться в переменной целого типа. Эта же операция попросту откидывает остаток у получившегося значения. Вот пример:

    123 / 10 = 12.3;      (Результат обычного деления)
    123 div 10 = 12;     (Результат работы операции div)

    Операция mod - получает остаток от деления целых чисел. При выполнении этой операции присходит выявление остатка от деления и именно он выноситься в результат. Вот пример:

    123 mod 10 = 3;
    17 mod 12 = 5;

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

    В нашей программе главной задачей является выявление всех цифр введенного числа, или его разрядов. Я реализую это за счет уменьшения порядка числа, предварительно получая последний знак. Как же это происходит?
    При получении остатка от деления числа на 10 выявляется последний, самый младший разряд, то есть та цифра в числе, которая меньше десяти. Это и есть первый разряд. Выводим его на экран, после чего уменьшаем число на это значение:

    Dec(A, B);
    Помните такую операцию? Это эквивалентно:
    A := A - B;

    Вот весь ход выполнения опрерации получения последного знака:

    * К примеру, мы ввели число 157:
    1. 157 mod 10 = 7; (Вот он, последний знак!)
    2. 157 - 7 = 150; (А вот мы его и отрезали!)

    * Если мы ввели число 1:
    1. 1 mod 10 = 1; (Опять последний знак - он же и первый)
    2. 1 - 1 = 0;
      (И опять мы его отрезаем, причем число стало равным нулю - оно как бы кончилось, однозначное ведь).

    После выполнения этих действий у имеющегося числа отсекается последняя цифра. Если вы не поняли, перечитайте все еще раз и попробуйте написать программу самостоятельно по шагам.
    Итак, после отсечения последней цифры нам нужно уменьшить это число в десять раз, то есть сдвинуть на один знак вправо, чтобы получить возможность выполнить все действия с самого начала и выявить следующий разряд. Для этого мы выполняем деление на 10 без остатка числа самого на себя. Задумайтесь, что происходит при такой операции?

    120 div 10 = 12;
    10020 div 10 = 1002;
    10 div 10 = 1;

    Видите, число подвигается на один разряд? Это налицо, не так ли? Ну а теперь вспомните наши манипуляции с операцией mod - отсечение последнего знака. Чтоже получиться, если после того, как мы сдвинули число опять выполнить вышеописанные действия? Верно, мы снова получим остаток от деления или последний разряд.
    Ну а теперь пустим эти две операции по кругу, организуем цикл. Причем цикл будет "пока число больше нуля", то есть пока оно у нас не кончиться. Сюда здорово вписывается цикл While, я не думаю пренебрегать этим и с удовольствием его использую.
    Вот такой вот алгоритм, для наглядного примера смотрите вышеприведенную программу...

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

    Написать программу получения числа из отдельно введенных однозначных чисел. Для этого постарайтесь придумать свой алгоритм, реализующий цикл для ввода чисел. Концом ввода должен служить нуль.
    Это задание будет приниматься на проверку. Присылать его нужно из формы на сайте
    http://www.plib.f2s.com/, раздела "Уроки для начинающих программистов >> отправить сообщение автору". Авторы писем, отправленных другим образом, про просмотр своей работы могут забыть.

    Вот такое задание до следующего выпуска. Правильные ответы будут опубликованы на сайте Библотека программиста, ваши работы я просмотрю и постараюсь оценить индивидуально.
    Чтож, сегодня мы с вами изучили довольно много полезного материала - не пренебрегайте этим и постарайтесь понять все до конца. Хочу также обратить особое ваше внимание на новый изученный алгоритм - разбивки чисел на разряды. Его понять просто необходимо, к тому же он не сложен и на нашем уровне обучения вполне по силам. Далее я постараюсь продемонстрировать широкие возможности его использования, но это в следующих выпусках, а пока занимайтесь!

    4. Вопросы - ответы

     1 
    Как в Турбо Паскале написать программу для Windows?
    Это невозможно. Turbo Pascal 7.0, который мы с вами используем, не поддерживает Windows-программы.
    Для написания Windows-программ предназначена более расширенная версия языка Паскаль - Borland Pascal 7.0, кроме того, чтобы писать в нем приложения для системы Windows необходимо знание дополнительных модулей - Object Windows, а также внутренних средств операционной системы. Мы этим в ближайшее время заниматься не будем.

     2 
    Как в Паскале очистить экран?
    ОЧЕНЬ распространенный вопрос. На самом деле я не должен рассказывать об этом, так как процедура очистки экрана в Паскале требует вызова дополнительных модулей. О этих модулях разговор будет в следующих выпусках и мне хотелось бы, как говориться "обо всем по порядку".
    Но тем не менее, я уверен, эта информация поможет многим, а полезна будет практически всем, поэтому привоже пример программы, реализующей очистку экрана. Программа без комментариев, просто шаблон, не более:

    Program Clear_Screen;

    uses Crt;

    begin

    ClrScr;
    Write('Вызовом предыдущей процедуры был очищен экран. ');
    Readln;
    end.

     3 
    С помощью чего можно в гипертексовом документе нарисовать слева меню, а справа текст?
    Делается это с помощью таблиц. Разговор это очень долгий, прошу по возможности не задавать таких вопросов, обо всем по порядку.

     4 
    Скажите, а рассылку Вы ведете один?
    Бывают и такие вопросы...
    Да, автор у рассылки один. И идея, и создание и оформление.

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


    Автор рассылки Эдуард Дмитриев (E-mail: ed1@mailru.com)

    Назад

    Hosted by uCoz