« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга


ПнВтСрЧтПтСбВс
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
    Популярное
Замечания о привилегиях в Interbase/Firebird

Объявление файла

Глава 7. Linux на службе

Два стиля ajax’а

Функция LocalFree

Eclipse. Создание stand-alone SWT приложений

CSS Sprites и их использование

Работа с графикой, прозрачные картинки

Функция AccessResource

Удаление компонента




    Архив файлов



    Сообщества

    Документация

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 88
Пользователей: 0

Статьи:: Turbo Pascal :: Работа с Pascal :: Цикл While



отправить ссылку другу версия для печати  Обсудить на форуме

Цикл While

В прошлом (практическом) уроке мы с вами закрепили тему циклов, прошли новые конструкции и попробовали кое-какие приемы программирования.

Сегодня тема циклов будет продолжена и мы с вами займемся одним из оставшихся - так называемым циклом 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. Это "+"?
      -> C = A + B;

    2. Это "-"?
      -> C = A - B;

    3. Это "*"?
      -> C = A * B;

  5. Вывести результат;

  6. Спросить - сначала?

  7. Если ответ утвердительный, то начать все сначала (переход к пункту 1);

  8. Конец нашей программки.

Вот исходный текст, реализующий этот алгоритм:

   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. Пока это число меньше нуля, делаем следующее:

  3. Получаем остаток от деления введенного числа на 10; Получившийся остаток и будет первым разрядом, т.е. единицами;

  4. Вычитаем получившийся остаток из имеющегося числа;

  5. Делим получившееся число на 10 без остатка

  6. Выводим его на экран;

  7. Спрашиваем, сначала?

  8. Если да, то переходим к пункту 1;

  9. Завершаем программу;

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

   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, я не думаю пренебрегать этим и с удовольствием его использую.

Вот такой вот алгоритм, для наглядного примера смотрите вышеприведенную программу...

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

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

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

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

Как в Турбо Паскале написать программу для Windows?

Это невозможно. Turbo Pascal 7.0, который мы с вами используем, не поддерживает Windows-программы.

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

Как в Паскале очистить экран?

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

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

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




Рубрика: Работа с Pascal




Вышел MySQL 5.1.30, первый стабильный рели....

MySQL

После публикации 29 тестовых версий анонсирован первый стабильный релиз MySQL 5.1, пригодный для промышленной эксплуатации и обеспечивающий увеличение производительности для "тяжелых" SQL запросов, по сравнению с MySQL 5.0, примерно на 15-20%. Главные новшества появившиеся в MySQL 5.1:


Подробнее... | Рубрика: MySQL | Добавлено: 28.11.2008

Тестирование параллельных программ.

Тестирование

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


Подробнее... | Рубрика: Тестирование | Добавлено: 28.11.2008

Архитектура AMD64 (EM64T).

Архитектура AMD

Аннотация. В статье кратко рассматривается архитектура AMD64 компании AMD и ее реализация EM64T компании Intel. Описаны особенности архитектуры, ее возможности, достоинства и недостатки.


Подробнее... | Рубрика: Архитектура AMD | Добавлено: 27.11.2008

Остальные статьи:

Платформа 2009. Определяя будущее
Windows Vista Bridge Sample Library - упра...
Оптимизация 64-битных программ
Подгрузка через AJAX HTML-кода, содержащег...
Обзор нового релиза самой мощной Ajax библ...
Firebug 1.3 и 1.4 alpha — что нового и инт...
Релиз Microsoft Silverlight 2.0. Что новог...
XML документация в C#
Курсоры в MySQL 5
Microsoft опубликовала подробности о сесси...
Microsoft делится подробностями о том, что...
Тестируем новый javascript от нового брауз...
MySQL Query Cache
Использование провайдеров компиляции в As...
Чего мы ждем от C# 4.0
Delphi 2009 и C++Builder 2009
Джоэл Спольски и Джеф Этвуд запустили новы...
Поиск кода Google /* что нового? */
10 jQuery скриптов для улучшения интерфейс...
Генераторы отчетов FastReport 4 и QuickRep...


Цитата дня (все,добавить):

Портал фрилансеров

работа на дому


    Рубрикатор

Программирование

C/С++
Обучение
Windows API
XAML
Моделирование
Паттерны
Visual Basic 7 .NET
WxWidgets
Функции WinApi
Функции С++
Разработка под Mac OS
Eiffel
Visual Studio 2008
UI дизайн
Алгоритмы
Конкурсные статьи
Turbo Pascal
Visual Studio
CASE-средства
Visual Studio 2005
Без VCL
Delphi
Тех. документация
Тестирование
Software Testing
ООП
TCP/IP
Google Android
Windows Installer
.NET Framework
Драйвера
C# C Sharp
Справка
Проектирование
Информ. системы
Visual Basic
Assembler
Оптимизация кода
Gtk+
Компоненты
Реинжиниринг
Управление проектами
Extreeme programming
Lotus Notes
Алгебраическое проектирование


Интернет технологии

PHP
Perl
ASP
WAP
Cookies
SSI
CGI
Web Servers
VB Script
DNS
CSS
XML
Html
Java Script
Java2ME
Firewall
Flash
.htaccess
Apache
VRML
Протоколы
Поисковые системы
Технология JAVA
Учебник по PHP
Учебник по JavaScript
Учебник по XML
Java Q&A
AJAX
DHTML
XHTML
Dreamweaver
Web 2.0
Python
Вебмастеру
Cisco
Ruby on Rails
Silverlight

Базы данных

Access
InterBase
MySQL
Oracle
ADO .NET
Основы SQL
Учебник по Access 2002
MS
Microsoft FoxPro
Доступ к данным
XML в MS SQL Server 2000
ODBC и MyODBC
Обучение
Caché
DB2
PostgresSQL
Sybase
Теория
Хранилища данных
Безопасность
Реляционные данные
MySQL и mSQL

Остальное:

Разное
Обзоры книг
Безопасность
Графика и дизайн
Юмор
Linux
Фракталы
Microsoft Axapta
Многоядерность
Сети
Microsoft Office
Работа
MS-DOS
Криптография
Графика и игроделание
Новости SDK
Системы защиты
Учебник по AutoCad
CVS
Windows XP
Windows Server 2003
Windows Vista
Windows 7
Мероприятия