• Авторизация


Структура простой программы на Паскале 01-10-2009 15:05


Программа на Паскале не просто состоит из операторов -- порядок следования этих операторов не случаен и образует определенную структуру. Структура простейшей программы описана в табл. 5.1.



Табл. 5.1. Структура простой программы на Паскале
Название раздела
Операторы раздела

Заголовок программы (необязателен)
program ИмяПрограммы;

Раздел описаний - необязателен, но, как правило, присутствует
const список констант;

var список переменных;

Тело программы - обязателен, содержит операторы программы
begin

операторы;

end.




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

Только последний оператор программы завершается точкой: end. , все остальные -- символом ;.

Если в программе нет констант, в ней будет отсутствовать раздел const, если нет и переменных -- раздел var.

При написании текста программы следует соблюдать несложные правила, облегчающие его последующие чтение и модификацию:

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

· на каждой строке обычно пишется один оператор (это облегчает и отладку программы);

· операторы одного уровня вложенности пишутся с одинаковым отступом слева; например, хорошим тоном считается после начала каждого блока (begin) отступать на следующей строке на символ или несколько символов вправо, а закрывать блок так, чтобы соответствующий end; находился под своим begin. Приведем пример неправильного и правильного структурирования:

program p1; var

a,b,c:real; begin

writeln ('Введите значения A и B:');read(a,b);

c:=a+b; writeln ('A+B=',c); c:=a-b;

writeln ('A-B=',c); end.

Текст этой программы структурирован явно неудачно, гораздо лучше он воспринимается так:

program p1;

var a,b,c:real;

begin

writeln ('Введите значения A и B:');

read (a,b);

c:=a+b;

writeln ('A+B=',c);

c:=a-b;

writeln ('A-B=',c);

end.

· основные действия программы комментируются: комментарием в Паскале считается любой текст, ограниченный фигурными скобками { ... } или символами (* ... *). Количество комментариев в программе никак не влияет на объем генерируемого машинного кода, они призваны, прежде всего, облегчить последующее чтение и модификацию исходного текста программы.

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

program Equation;

var a,b,c,d,x1,x2:real; begin

writeln;

writeln ('Введите коэффициенты a,b,c:');

read (a,b,c);

d:=sqr(b)-4*a*c;

x1:=(-b+sqrt(d))/(2*a);

x2:=(-b-sqrt(d))/(2*a);

writeln ('Корни уравнения');

writeln (x1:10:2,x2:10:2);

readln; readln;

end.

В разделе описаний программы всем переменным, требуемым для решения задачи, присвоен тип real, и этот выбор вполне очевиден -- коэффициенты a, b и с -- не обязательно целые значения. "Лишний" оператор writeln; перед приглашением к вводу -- гарантия того, что приглашение будет напечатано с начала пустой строки, ведь мы пока не умеем очищать экран, и, возможно, при запуске нашей программы курсор находится не в начале строки. После вычисления дискриминанта и корней x1, x2 (условие d≥0 мы пока не проверяем), на экран печатается информационное сообщение "Корни уравнения", а затем с новой строки выводятся значения x1 и x2 с соблюдением указанных ширины и точности вывода. Наконец, два оператора readln; в конце программы позволяют ей дождаться, пока пользователь не нажмет клавишу Enter. "Удвоение" оператора здесь связано с тем, что один раз мы уже нажимали Enter после ввода данных, и первый readln; прочитает именно это нажатие, а второй будет ждать еще одного. Будь ввод данных организован в виде a:=1; b:=2; c:=0; или readln(a,b,c);, нам хватило бы и одного readln;. Однако, оператор readln(a,b,c); потребовал бы от пользователя ввести все 3 числа в одной строке, а задание фиксированных значений a, b, c уменьшило бы до нуля ее полезность. В дальнейшем мы узнаем более гибкие способы программирования реакции программы на действия пользователя.
комментарии: 0 понравилось! вверх^ к полной версии
Компилятор и оболочка Turbo Pascal 01-10-2009 15:01


Кратко рассмотрим основные действия с этой программой. После установки программы из папки Паскаля или с помощью ярлыка запускается файл с именем turbo.exe. Основные элементы окна Турбо Паскаля приведены на рис. 6.1.




Рис. 6.1. Окно программы Turbo Pascal



Как видно на рис. 6.1, устройство окна несколько отличается от стандартного окна Windows.

Для входа в верхнее меню следует нажать клавишу F10 или сделать щелчок мышью на нужном пункте. Если ни одно окно не открыто или необходимо окно для новой программы, в меню File выберите пункт New. Для открытия ранее сохраненной программы в этом же меню выберите Open или просто нажмите F3 из основного окна. Выбрать нужную программу можно в появившемся диалоговом окне, возможно, для этого потребуется сменить папку.

Если открыто сразу несколько окон, переключаться между ними можно, нажимая при нажатой левой Alt цифровую клавишу с номером нужного окна (от 1 до 9). Получить список всех окон можно комбинацией клавиш Alt+0, закрыть текущее окно -- Alt+F3

После ввода программы (а лучше несколько раз в процессе ввода) ее следует сохранить на диске. Для этого в меню File достаточно выбрать команду Save или нажать F2 из окна программы. При первом сохранении программе нужно дать имя. Помните, что Паскаль разрабатывался для операционной системы MS-DOS и даваемые файлам имена должны включать в себя только латинские буквы и цифры, а по длине не превышать 8 символов. Тип файла .pas можно не указывать, он добавится к имени автоматически.

Для сохранения файла с программой на дискету или открытия его с дискеты проще всего в окне ввода указать a: и нажать Enter. Аналогично можно перейти к другим сменным носителям, введя их системное имя диска.

После сохранения программы, для ее компиляции и выполнения достаточно нажать комбинацию клавиш Ctrl+F9. Если в процессе компиляции найдена синтаксическая ошибка, компилятор сообщит о ней и установит курсор на строку, содержащую ошибку. После исправления ошибки нажмите Ctrl+F9 еще раз. По завершении программы, если в ней не предусмотрено никакого останова, произойдет автоматический возврат в окно с исходным текстом. Вернуться к окну вывода программы после ее выполнения можно, нажав Alt+F5.

Вследствие алгоритмических ошибок или аппаратных проблем запущенная программа может "зависнуть", например, бесконечно выполняя неправильно запрограммированный цикл. В этом случае, при работе из оболочки Паскаля, можно попытаться прервать ее сочетанием клавиш Ctrl+Break.

Переключение на русский язык и обратно из оболочки Турбо Паскаля зависит от настроек ОС, уточните их у преподавателя или оператора.

Переключение в полноэкранный режим и обратно, как и для других приложений DOS, выполняется сочетанием клавиш Alt+Enter.

По умолчанию программа Turbo Pascal не создает исполняемых файлов *.exe. Чтобы она начала это делать, достаточно в верхнем меню Compile установить пункт-переключатель Destination в значение Disk (значение по умолчанию -- Memory).

Оболочка Паскаля включает удобные средства отладки программ, основные требуемые команды собраны в меню Debug. Для выполнения программы по строкам достаточно нажимать F7 или F8. Разница между назначениями этих клавиш в том, что нажатие F7 пошагово выполняет программу с входом во все возможные подпрограммы, а F8 -- нет. Пока тема "Подпрограммы" не изучена, разницы в действии клавиш не будет заметно. Строка, которая будет выполняться следующей, выделена светло-зеленым цветом. Перейти сразу к нужному месту в программе можно, установив курсор на соответствующую строку и нажав клавишу F4. Выйти из режима пошагового выполнения и прервать работу отладчика позволяет сочетание клавиш Ctrl+F2.

В процессе пошагового выполнения можно посмотреть и даже изменить значения любых переменных. Для этого достаточно установить курсор на имя нужной переменной и нажать сочетание клавиш Ctrl+F4. На экране должно появиться диалоговое окно "Evaluate and Modify". В поле ввода Expression уже показано имя переменной, на которой стоял курсор. Если это не так, здесь можно задать имя любой доступной переменной или ввести произвольное выражение на Паскале. Нажатие Enter или кнопки Evaluate выводит результат в поле Result. В поле New Value можно, не прерывая пошагового выполнения, изменить значение переменной. Если предложенное изменение возможно, после нажатия кнопки Modify оно будет показано в поле Result, в противном случае там выведется сообщение "Cannot be modified". Таким образом, окно "Evaluate and Modify" позволяет гибко тестировать поведение программы при различных входных данных.

Наконец, в Паскаль встроена мощная система помощи. Нажатие клавиши F1 вызывает окно помощи по редактору, а Shift+F1 -- индекс оглавления справочной системы. В тексте помощи ссылки на другие разделы выделены желтым цветом, а переходить по ссылкам можно клавишами Tab и Shift+Tab или клавишами со стрелками. Нажатие Alt+F1 возвращает к чтению предыдущей статьи. Пользуясь выделением с помощью мыши или клавишами со стрелками
Читать далее...
комментарии: 0 понравилось! вверх^ к полной версии

Разветвляющийся вычислительный процесс и условный оператор 01-10-2009 14:59


Pers.narod.ru. Обучение. Учебник по Паскалю. Глава 7

7. Разветвляющийся вычислительный процесс и условный оператор



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

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


7.1. Логические выражения



Логические выражения (ЛВ) строятся из АВ, операций отношения, логических операций и круглых скобок.

Результатом вычисления ЛВ является одно из двух значений: true или false.


7.2. Операции отношения



Операции отношения (сравнения) имеют следующий общий вид:

АВ1 ОО АВ2

где АВ -- арифметические выражения, ОО -- один из следующих знаков операций:

< <= > >= = <>

Последний знак обозначает отношение "не равно". Обратите также внимание на запись отношений "меньше или равно", "больше или равно".

В любое логическое выражение должна входить хотя бы одна операция отношения.

Приведем примеры ЛВ, включающих одну ОО:

d<0 -- выбор ветви вычислений зависит от значения d;

sqr(x)+sqr(y)<=sqr(r) -- результат будет равен true для точек с координатами (x, y), лежащих внутри круга радиуса R с центром в начале координат;

cos(x)>1 -- результат этого ЛВ всегда равен false.

К вещественным значениям в общем случае неприменима операция = ("равно") из-за неточного представления этих значений в памяти компьютера. Поэтому для вещественных переменных отношение вида a=b часто заменяется на abs(a-b)1) всегда даст значение true.

Операция AND связывает не менее двух логических выражения (является бинарной). Ее результат равен true, если все выражения истинны или false, если хотя бы одно из выражений ложно.

В качестве примера распишем выражение . Т. к. операции принадлежности в Паскале нет, используем операцию AND и операции отношения: (x>=a) and (x<=b).

Математическое выражение a,b,c>0 (одновременно) будет иметь вид (a>0) and (b>0) and (c>0).

Операция OR также связывает не менее двух логических выражений. Ее результат равен true, если хотя бы одно выражение истинно и false, если все выражения ложны.

Распишем выражение . На Паскале оно будет иметь вид(xb). Другой способ связан с применением операции NOT: not ((x>=a) and (x<=b)).

Условие "хотя бы одно из значений a,b,c положительно" может быть записано в виде (a>0) or (b>0) or (c>0) .

Условие "только одно из значений a,b,c положительно" потребует объединения возможностей операций AND и OR:

(a>0) and (b<=0) and (c<=0) or

(a<=0) and (b>0) and (c<=0) or

(a<=0) and (b<=0) and (c>0).

Операция XOR, в отличие от OR, возвращает значение "ложь" (false) и в том случае, когда все связанные ей логические выражения истинны. Чтобы лучше уяснить это отличие, составим так называемую таблицу истинности двух логических операций (табл. 7.2). Для краткости значение false обозначим нулем, а true -- единицей. Для двух логических аргументов возможно всего 4 комбинации значений 0 и 1.



Табл. 7.2. Таблица истинности операций OR и XOR
Аргумент A
Аргумент B
A or B
A xor B

0
0
0
0

0
1
1
1

1
0
1
1

1
1
1
0




В качестве примера использования операции XOR запишем условие "только одно из значений a,b положительно":

(a>0) xor (b>0).

К сожалению, записать условие "только одно из значений a,b,c положительно" в напрашивающемся виде (a>0) xor (b>0) xor (c>0) нельзя -- результат этого выражения будет равен true и в случае, когда все три значения положительны. Связано это с тем, что при последовательном расчете логических выражений слева направо (1 xor 1) xor 1 будет равно 0 xor 1 = 1.

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

x := x xor true; writeln ('x=', x);

x := x xor true; writeln ('x=', x);

Независимо от начального значения логической переменной x, второе выведенное на экран значение будет логическим отрицанием первого. В реальной практике конструкции подобные x := x xor true; не дублируются в коде многократно, а применяются внутри цикла (см. гл. 9).

Приоритет логических операций следующий: самая старшая операция -- not, затем and, следующие по приоритету -- or и xor (равноправны между собой), самый низкий приоритет имеют операции отношения. Последнее служит причиной того, что в составных условиях отдельные отношения необходимо заключать в круглые скобки, как и сделано во
Читать далее...
комментарии: 0 понравилось! вверх^ к полной версии
Директивы компилятора и обработка ошибок ввода 01-10-2009 14:56


Компилятор Паскаля -- сложное приложение, имеющее множество настроек. При написании учебных программ большинство этих настроек не имеют значения, но некоторые из них окажутся нам полезны. Для управления компилятором существует 2 основных возможности: настройка режимов работы с помощью верхнего меню Options оболочки Turbo Pascal и настройка конкретной программы с помощью директив компилятора, которую мы кратко рассмотрим. В общем виде директива компилятора представляет собой конструкцию вида {$X+} или {$X-}, где X -- латинская буква. Вариант со знаком "+" включает некоторый режим работы компилятора (например, строгий контроль программой соответствия типов данных, вывод системных диагностических сообщений и т. д.), а вариант со знаком "-" выключает его. Расположение директив, в общем, произвольно, однако, директивы, влияющие на всю программу, принято располагать в самом начале файла с исходным текстом. Фигурные скобки комментария { ... } необходимы как часть синтаксиса директивы.

Подробную информацию о назначении всех директив можно получить в справочной системе оболочки. Основные директивы компилятора также кратко описаны в Приложении 2.

Наиболее полезной для нас выглядит директива {$I-}/{$I+}, соответственно, выключающая и включающая автоматический контроль программой результатов операций ввода/вывода (в/в). К операциям в/в относятся, в числе прочего, ввод данных пользователем, вывод строки на принтер, открытие файла для получения или вывода данных и т. п. Понятно, что даже несложная учебная программа выглядит лучше, если она умеет реагировать на неправильные действия пользователя или возникающие ошибки не просто выводом маловразумительного системного сообщения на английском языке, а доступным неискушенному пользователю текстом. По умолчанию контроль в/в включен и системные сообщения об ошибках генерируются автоматически. Все они кратко приведены в Приложении 3. Для замены системной диагностики своей собственной следует, во-первых, отключить директиву контроля оператором {$I-}, а во-вторых, сразу же после оператора, который мог породить ошибку, проверить значение, возвращаемое системной функцией IoResult. Эта функция возвращает ноль, если последняя операция в/в прошла успешно, в противном случае возвращается ненулевое значение. После завершения "критического" оператора директиву следует включить снова, чтобы не создавать потенциально опасных ситуаций в коде, который будет писаться далее. Приведем пример, написав "расширенную" программу решения квадратного уравнения, корректно реагирующую на возникающие ошибки:

uses printer;

var a,b,c,d,x1,x2:real;

begin

writeln;

writeln ('Введите коэффициенты a,b,c:');

{$I-} read (a,b,c); {$I+}

if IoResult<>0 then begin

{Возникла ошибка!}

writeln ('Вы не ввели 3 числа, ',

'это что-то другое!');

reset (input); {очищаем стандартный

поток ввода перед ожиданием нажатия Enter}

readln;

halt; {а этим оператором можно

аварийно завершить программу}

end;

d:=sqr(b)-4*a*c;

if d<0 then begin

writeln ('Ошибка - дискриминант<0');

reset (input); readln; halt;

end;

x1:=(-b+sqrt(d))/(2*a);

x2:=(-b-sqrt(d))/(2*a);

{$I-}

writeln (lst,'x1=',x1:8:2,' x2=',x2:8:2);

{$I+}

if IoResult<>0 then

writeln ('Не удалось напечатать')

else writeln ('Результаты напечатаны');

reset (input); readln; halt;

end.

Специальной директивы для контроля математических ошибок в Паскале не предусмотрено, но это почти всегда можно сделать обычными проверками корректности данных. Обратите внимание на альтернативное решение проблемы "двух readln" в этом коде, а также на новый оператор halt и способ контроля того, удалось ли вывести строку на принтер.

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

Для работы с вещественными числами с двойной точностью (тип double) может также понадобиться указать перед программой директиву {$N+}, позволяющую сгенерировать код для аппаратной обработки таких чисел.
комментарии: 0 понравилось! вверх^ к полной версии
Оператор цикла. Циклы с предусловием и постусловием 01-10-2009 14:54


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

Повторяемый блок вычислений называют телом цикла. В теле цикла должно быть обеспечено изменение значения счетчика, чтобы он мог завершиться. Если тело цикла состоит более чем из одного оператора, оно заключается в операторные скобки begin ... end;. Однократное выполнение тела цикла называют его шагом.

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

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





Рис. 9.1. Блок-схемы циклов с предусловием и постусловием



Для цикла с постусловием сначала выполняется тело цикла, затем управление передается на проверку условия. В зависимости от истинности или ложности условия, тело цикла выполняется повторно или же происходит переход к оператору, следующему за телом цикла. Всё, сказанное о возможном зацикливании для цикла с предусловием, справедливо и для цикла с постусловием.

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

В языке Паскаль реализованы оба вида циклов. Цикл с предусловием имеет следующий общий вид:

while логическое_выражение do begin

{операторы тела цикла}

end;

Работу цикла можно описать словами: "пока логическое выражение истинно, повторяется тело цикла".

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

Общая запись цикла с постусловием следующая:

repeat

{операторы тела цикла}

until логическое_выражение;

Работает цикл с постусловием следующим образом: "тело цикла повторяется до тех пор, пока логическое выражение не станет истинным". Обратите внимание, что, в отличие от while, цикл repeat в Паскале работает, пока условие ложно. Это отличие подчеркивается использованием ключевого слова until ("до тех пор, пока не") вместо while ("до тех пор, пока"). Кроме того, в виде исключения, тело цикла repeat, даже если оно состоит из нескольких операторов, можно не заключать в операторные скобки.

Довольно часто циклы взаимозаменяемы. Представим, например, что для каждого из значений переменной x=1, 2, ... ,20, нужно выполнить некоторый расчет (математически этот закон изменения x можно записать как или ). Это можно сделать как в цикле while:

x:=1;

while x<=20 do begin

{операторы расчета}

x:=x+1;

end;

так и с помощью repeat:

x:=1;

repeat

{операторы расчета}

x:=x+1;

until x>20;

Как видно из листинга, управляющей переменной x в обоих случаях присвоено начальное значение 1, оба цикла изменяют значение x и, соответственно, условие цикла, оператором x:=x+1;, но для цикла repeat условие "перевернуто" ("пока x не станет больше 20"), а тело не заключено в операторные скобки.

Зачастую использование одного из циклов выглядит предпочтительней. Например, обработка ввода пользователя с клавиатуры удобней с помощью repeat (сначала пользователь должен нажать клавишу, затем следуют проверки и обработка).
комментарии: 0 понравилось! вверх^ к полной версии
Цикл со счетчиком и досрочное завершение циклов 01-10-2009 14:53


Прежде, чем перейти к примерам, обсудим еще ряд проблем, связанных с циклами. Как для while, так и для repeat, во-первых, нигде в явном виде не задается число шагов цикла (хотя его обычно можно вычислить), во-вторых, при использовании обоих циклов программист должен заботиться об изменении управляющей переменной. Между тем, весьма распространены задачи, где объем последовательно обрабатываемых данных известен заранее (а значит, известно и требуемое число шагов цикла), а управляющая переменная меняется с шагом, равным единице. Рассмотренный выше пример с двадцатью значениями x относится именно к таким задачам. Поэтому для обработки заранее известного объема данных с шагом по управляющей переменной, равным единице, вместо цикла while используется цикл со счетчиком (цикл for). Его общий вид следующий:

for счетчик := НЗ to КЗ do begin

{операторы тела цикла}

end;

Здесь счетчик -- целочисленная переменная, НЗ (начальное) и КЗ (конечное) значения -- целочисленные выражения или константы. Тело цикла образовано не менее чем одним оператором, если этот оператор единственный, операторные скобки можно не писать. Работает цикл for следующим образом: счетчик автоматически меняется от начального значения до конечного включительно, для каждого значения счетчика повторяется тело цикла. После каждого шага цикла значение счетчика автоматически увеличивается на единицу. Если требуется, чтобы значение счетчика уменьшалось, а не увеличивалось, вместо ключевого слова to используется downto.

Подобно while, цикл for может не выполниться и ни разу -- если начальное значение управляющей переменной сразу же больше конечного (при использовании to) или меньше (при использовании downto).

Запишем рассмотренный выше цикл по переменной x с помощью оператора for:

for x:=1 to 20 do begin

{операторы тела цикла}

end;

Удобства очевидны -- границы изменения x заданы сразу же при входе в цикл, а выполнять шаг по x отдельным оператором не требуется. Понятны и ограничения -- x должен быть описан с типом данных integer, а в случае изменения значения x с шагом, не равным единице, использовать for вместо while не удалось бы.

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

x:=1;

while x<10 do begin

y:=ln(x);

if y>2 then x:=10;

{При y>2 цикл нужно завершить}

x:=x+0.5;

end;

Однако, во избежание трудноуловимых ошибок, управляющую переменную не принято менять иначе, чем для выполнения шага цикла. Например, после оператора if y>2 then x:=10; в нашем листинге выполнение текущего шага продолжится, что чревато лишними или неправильными вычислениями. Кроме того, текст такой программы воспринимается нелегко.

Поэтому для досрочного выхода из цикла существует оператор break (от англ. "to break" -- прервать), немедленно прекращающий его выполнение:

x:=1;

while x<10 do begin

y:=ln(x);

if y>2 then break;

x:=x+0.5;

end;

Указание break здесь передаст управление на оператор, следующий непосредственно за циклом. В отличие от предыдущего примера, здесь не будет выполняться часть тела цикла, следующая за break;.

Для немедленного продолжения цикла со следующего шага используется оператор continue (от англ. "to continue" -- продолжить):

var n:integer;

begin

repeat

writeln ('Введите положительное число:');

read (n);

if n<1 then continue;

{Если введено n<1, снова запросить число}

{Операторы обработки числа}

break; {Выход из цикла обработки}

until false;

end.

В этом примере оператор continue использован для повторного перехода к вводу n, если введено n<1. Так как цикл обработки здесь -- бесконечный, для выхода из него необходим break;. Кроме того, пример показывает одну из возможностей контроля правильности ввода данных. Указав директиву {$I-}, изученную в гл. 8, мы могли бы защитить программу и от ввода пользователем нечисловых значений в качестве n.

В теме "Кратные циклы" второй части курса будет рассмотрен оператор goto, также способный решить проблему аварийного завершения циклов.
комментарии: 0 понравилось! вверх^ к полной версии
Типовые алгоритмы табулирования функций, вычисления количества, суммы и произведения 01-10-2009 14:51


Типовые алгоритмы табулирования функций, вычисления количества, суммы и произведения



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

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


11.1. Алгоритм табулирования



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

В общем виде алгоритм можно описать так:

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

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

3. в конце шага цикла значение управляющей переменной (обозначим ее x) изменяется оператором вида x:=x+d;, где d -- заданный шаг по управляющей переменной.

В качестве примера составим таблицу синусов в пределах от 0 до π с шагом по аргументу 0.25. Обозначим аргумент как x, значение синуса от x обозначим как y. В простейшем случае программа табулирования может выглядеть так:

var x,y:real;

begin

writeln('x':10,'sin(x)':10);

{печать заголовка таблицы до цикла}

x:=0; {начальное значение аргумента}

while x<=piХ6 do begin

y:=sin(x); {вычисление функции}

writeln (x:10:2, y:10:2);

{печать строки таблицы}

x:=x+0.25; {шаг по x}

end;

end.

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

, значения a, b вводятся пользователем.

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

var x,f,a,b,dx:real;

n:integer; {счетчик выведенных строк}

begin

repeat {Цикл ввода с контролем

правильности значений: a,dx,b должны быть

числами, dx>0, a+dx должно быть меньше b}

writeln ('Введите a,dx,b:');

{$I-}read (a,dx,b);{$I+}

if IoResult <> 0 then begin

writeln ('Вы не ввели 3 числовых ',

'значения, попробуем еще раз');

continue;

end;

if (dx<=0) or (a+dx>=b) then begin

writeln ('Вы не ввели допустимые ',

'данные, попробуем еще раз');

continue;

end

else break;

until false;

{Печать заголовка таблицы}

writeln;

writeln ('x':10,'f(x)':10);

x:=a;

n:=2; {2 строки уже использованы}

while x<=bХ6 do begin

{в условии цикла учитываем возможную

погрешность работы с real!}

if x<=0 then f:=sqr(x)*x

else f:=exp(1/3*ln(abs(x)));

{корень 3 степени взяли через exp и ln}

writeln (x:10:2,f:10:2);

n:=n+1;

if n=24 then begin

{На экране консоли по умолчанию 25 строк}

write ('Нажмите Enter...');

reset (input); readln;

n:=1;

end;

x:=x+dx;

end;

writeln ('Таблица выведена');

reset (input); readln;

end.

Как видно из примера, основной порядок действий -- такой же, как в предыдущей задаче. Так как экран консоли по умолчанию содержит всего 25 строк, с помощью переменной n мы дополнительно контролируем число уже выведенных строк и делаем по заполнении экрана паузу до нажатия пользователем клавиши Enter.

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

Известна стоимость единицы товара. Составить таблицу стоимости 1, 2, ..., K единиц товара, значение K вводится.

Так как число единиц товара -- заведомо целое, при программировании задачи будет удобен цикл for:

var t:real;

i,k:integer;

begin

writeln;

writeln ('Стоимость единицы товара:');

read (t);

writeln ('Количество единиц товара:');

read (k);

writeln ('Единиц':10,'Стоимость':10);

for i:=1 to k do

writeln (i:10,(i*t):10:2);

end.

Здесь для простоты мы исключили сделанные в предыдущем примере проверки. Стоимость единицы товара обозначена t, переменная i необходима для перебора возможных значений единиц товара в цикле for. Поскольку счетчик цикла for автоматически меняется с шагом 1, а оператором
Читать далее...
комментарии: 0 понравилось! вверх^ к полной версии
Типовые алгоритмы поиска максимума и минимума 01-10-2009 14:50


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

Рассмотрим алгоритм в общем виде:

1. описать для каждого максимума и минимума по одной переменной того же типа, что анализируемые данные;

2. до цикла максимуму присваивается либо заведомо малое для анализируемых данных значение, либо первый элемент данных; минимуму присваивается либо заведомо большое для анализируемых данных значение, либо первый элемент данных;

3. в теле цикла каждый подходящий для поиска элемент данных t обрабатывается операторами вида:
if t>max then max:=t; -- для максимума;
if tmax не выполнится ни разу и ответом будет max, равное нулю, что неправильно. Выбор заведомо малого начального значения max (например, значение -1E30, т. е., -1030, вряд ли встретится в любых реальных данных) гарантирует, что условие t>max выполнится хотя бы раз и максимум будет найден. Альтернативный способ -- присвоить переменной max значение отдельно вычисленного первого элемента последовательности данных. В этом случае ответ либо уже найден, если первый элемент и есть максимальный, либо будет найден в цикле.

Аналогичные рассуждения помогают понять, почему минимуму следует присваивать в качестве начального значения заведомо большое число.

Перейдем к примерам. Для функции y(x)=sin2(x), найти минимальное среди положительных и максимальное значения.

Обозначив искомые значения min и max соответственно, напишем следующую программу:

var x,y,max,min:real;

begin

x:=-pi/3;

max:=-2;

min:=2; {эти начальные значения

- заведомо малое и большое для синуса}

while x<=pi/3Х6 do begin

y:=sqr(sin(x));

if y>0 then

{ищем min только среди положительных!}

if ymax then max:=y;

x:=x+pi/24;

end;

writeln ('Минимум =',min:8:2);

writeln ('Максимум=',max:8:2);

reset (input); readln;

end.

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

Последовательность T(k) задана соотношениями T(k)=max(sin k, cos k), k=1, 2, ... ,31. Найти номера максимального и минимального элементов последовательности.

Поиск номеров не избавит нас от необходимости поиска значений. Поэтому, кроме переменных min и max, нам понадобятся две целочисленные переменные для хранения номеров минимального и максимального значений, обозначим их kmin и kmax соответственно. Обратите также внимание, что на каждом шаге цикла дополнительно потребуется находить максимальное из значений sin(k) и cos(k), для занесения его в переменную t.

var t,max,min:real;

k,kmin,kmax:integer;

begin

min:=1e30;

max:=-1e30;

{задаем "надежные" значения,

близкие к плюс и минус бесконечности}

for k:=1 to 31 do begin

if sin(k)>cos(k) then t:=sin(k)

else t:=cos(k);

if tmax then begin

max:=t; kmax:=k;

end;

end;

writeln ('Номер мин. элемента =',kmin);

writeln ('Номер макс. элемента=',kmax);

reset (input); readln;

end.
комментарии: 0 понравилось! вверх^ к полной версии
Решение учебных задач на циклы 01-10-2009 14:48


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

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

Задана функция и ее разложение в ряд:

n=0, 1, 2, ... (здесь n! обозначает факториал числа n, равный 1*2*3*...*n; при этом 0!=1). Найти число элементов ряда k, требуемое для достижения заданной точности ε.

Перед нами -- типичная задача на ряды. С ростом величины n слагаемые становятся все меньше, равно как и модуль разности между двумя соседними слагаемыми. Поэтому под достижением заданной точности будем понимать выполнение условия где sn, sn-1 -- суммы ряда, вычисленные на текущем и предыдущем шагах цикла, а значение ε задается малым числом, от 10-6 и ниже. Для вычисления x2n введем переменную xn, которую на каждом шаге цикла будем домножать на x2, аналогично, для вычисления текущего значения факториала используем переменную nf. Иной подход потребовал бы большого количества повторных вычислений на каждом шаге цикла, плюс был бы чреват большими потерями точности. Для вычисления (-1)n было бы странно использовать формулу ax=exln a -- вполне достаточно завести целочисленную переменную znak, равную 1, которая на каждом шаге цикла будет менять свое значение на противоположное оператором znak:=-znak;. Кроме того, так как требуемое число шагов заранее неизвестно, используем для всех основных переменных более точный тип double вместо real.

Реализуем все сказанное в следующей программе:

{$N+} {Совместимость с процессором 80287 -

для использования double}

var x,sn,sn1,xn,nf,eps:double;

k,n:longint;

znak:integer;

begin

writeln ('Введите значение x:');

read (x);

writeln ('Введите требуемую точность:');

read (eps);

sn1:=0;

sn:=0;

k:=0;

n:=0;

xn:=1;

nf:=1;

znak:=1;

repeat

sn1:=sn; {Текущая сумма стала

предыдущей для следующего шага}

sn:=sn+znak*xn/nf; {Выполняем шаг цикла}

{Меняем переменные для следующего шага:}

znak:=-znak;

xn:=xn*sqr(x);

nf:=nf*(n+1)*(n+2);

n:=n+2;

k:=k+1;

until abs(sn1-sn)
комментарии: 0 понравилось! вверх^ к полной версии
Одномерные массивы. Описание, ввод, вывод и обработка массивов на Паскале 01-10-2009 14:47


Массивом называют упорядоченный набор однотипных переменных (элементов). Каждый элемент имеет целочисленный порядковый номер, называемый индексом. Число элементов в массиве называют его размерностью. Массивы используются там, где нужно обработать сразу несколько переменных одного типа -- например, оценки всех 20 студентов группы или координаты 10 точек на плоскости. Строку текста можно рассматривать как массив символов, а текст на странице -- как массив строк.

Массив описывается в разделе var оператором следующего вида:

var ИмяМассива: array [НИ .. ВИ] of Тип;

Здесь

НИ (нижний индекс) -- целочисленный номер 1-го элемента массива;

.. -- оператор диапазона Паскаля (см. п. 7.8);

ВИ (верхний индекс) -- целочисленный номер последнего элемента;

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

Опишем несколько массивов разного назначения.

var a: array [1..20] of integer;

Здесь мы описали массив с именем A, состоящий из 20 целочисленных элементов;

var x,y : array [1..10] of real;

Описаны 2 массива с именами x и y, содержащие по 10 вещественных элементов;

var t : array [0..9] of string;

Массив t состоит из 10 строк, которые занумерованы с нуля.

Легко увидеть, что размерность (число элементов) массива вычисляется как ВИ - НИ + 1.

Для обращения к отдельному элементу массива используется оператор вида ИмяМассива [Индекс].

Здесь Индекс -- целочисленный номер элемента (может быть целочисленным выражением или константой). Индекс не должен быть меньше значения нижнего или больше верхнего индекса массива, иначе возникнет ошибка "Constant out of range". Отдельный элемент массива можно использовать так же, как переменную соответствующего типа, например:

A[1]:=1;

x[1]:=1.5; y[1]:=x[1]+1;

t[0]:='Hello';

В этой главе мы изучаем одномерные массивы, в которых каждый элемент имеет один номер (индекс), характеризующий его положение в массиве. В математике понятию одномерного массива из n элементов соответствует понятие вектора из n компонент: A = {Ai}, i=1, 2 ,..., n.

Как правило, ввод, обработка и вывод массива осуществляются поэлементно, с использованием цикла for.

Простейший способ ввода -- ввод массива с клавиатуры:

const n = 10;

var a: array [1..n] of real;

i:integer;

begin

writeln ('Введите элементы массива');

for i:=1 to n do read (A[i]);

Размерность массива определена константой n, элементы вводятся по одному в цикле for -- при запуске этой программы пользователю придется ввести 10 числовых значений. При решении учебных задач вводить массивы "вручную", особенно если их размерность велика, не всегда удобно. Существуют, как минимум, два альтернативных решения.

Описание массива констант удобно, если элементы массива не должны изменяться в процессе выполнения программы. Как и другие константы, массивы констант описываются в разделе const. Приведем пример такого описания:

const a:array [1..5] of real=(

3.5, 2, -5, 4, 11.7

);

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

Формирование массива из случайных значений уместно, если при решении задачи массив служит лишь для иллюстрации того или иного алгоритма, а конкретные значения элементов несущественны. Для того чтобы получить очередное случайное значение, используется стандартная функция random(N), где параметром N передается значение порядкового типа. Она вернет случайное число того же типа, что тип аргумента и лежащее в диапазоне от 0 до N-1 включительно. Например, оператор вида a[1]:=random(100); запишет в a[1] случайное число из диапазона [0,99].

Для того чтобы при каждом запуске программы цепочка случайных чисел была новой, перед первым вызовом random следует вызвать стандартную процедуру randomize;, запускающую генератор случайных чисел. Приведем пример заполнения массива из 20 элементов случайными числами, лежащими в диапазоне от -10 до 10:

var a:array [1..20] of integer;

i:integer;

begin

randomize;

for i:=1 to 20 do begin

a[i]:=random(21)-10;

write (a[i]:4);

end;

end.

Еще более удобный путь -- чтение элементов массива из текстового или двоичного файла. Об этом рассказывается в гл. 21 и 22.

К массивам применимы все типовые алгоритмы, изученные в теме "Циклы". Приведем один пример, в котором вычисляется сумма s положительных элементов массива.

var b:array [1..5] of real;

s:real; i:integer;

begin

writeln ('Введите 5 элементов массива');

for i:=1 to 5 do read (b[i]);

s:=0;

for i:=1 to 5 do if b[i]>0 then s:=s+b[i];

Вывод массива на экран также делается с помощью цикла for.

for i:=1 to 5 do write (b[i]:6:2);

Здесь 5 элементов массива b напечатаны в одну строку. Для вывода одного элемента на одной строке можно было бы использовать оператор writeln вместо write.

Существенно то, что если обработка массива осуществляется
Читать далее...
комментарии: 0 понравилось! вверх^ к полной версии
15. Решение типовых задач на массивы 01-10-2009 14:46


В гл. 14 мы подчеркивали, что типовые алгоритмы, изученные в теме "Циклы", в полной мере применимы и к массивам. Занимая определенный объем оперативной памяти, однажды полученные элементы массива остаются доступными весь сеанс работы программы и не требуют повторного вычисления или чтения из файла. Это порождает круг приложений, связанных с типовой обработкой наборов данных -- вычисление математических и статистических характеристик векторов, объединение массивов или поиск нужных значений в них и т. д. Другие интересные примеры, такие как подсчет частоты встречаемости элементов в массиве, задача сортировки (упорядочения) данных, будут рассмотрены в гл. 16.

1. Найти сумму, скалярное произведение и длину двух векторов произвольно заданной размерности. Размерность не может превышать значения 100.

Предельную размерность массивов зададим константой size=100. Размерность реальных векторов a и b, с которыми работает программа, не обязательно столь велика, обозначим ее n и позаботимся о том, чтоб при вводе значения n соблюдалось соотношение 2≤n≤size. Введем вектор a с клавиатуры, а вектор b сгенерируем из случайных вещественных чисел, принадлежащих диапазону от 0 до 10. Для этого достаточно умножить на 10 значение, возвращаемое стандартной функцией random, если она вызвана без параметров: b[i]:=random*10;.

При написании кода мы применим изученный в гл. 8 прием контроля правильности вводимых данных с помощью директивы компилятора и стандартной функции IoResult.

Как известно из математики, сумма векторов a и b ищется поэлементно по правилу ci=ai+bi, скалярное произведение может быть вычислено по формуле , а длина вектора a из n элементов ищется по формуле .

const size=100;

var a,b,c:array [1..size] of real;

n,i:integer;

la,lb,s:real;

begin

repeat

writeln;

write ('Введите размерность A и B, ',

'значение от 2 до ',size,':');

{$I-}readln (n);{$I+}

if (IoResult<>0) or (n<2) or (n>size)

then

writeln ('Неверный ввод, повторите')

else break;

until false;

writeln ('Введите вектор A из ',

n,' элементов:');

for i:=1 to n do begin

repeat

write ('A[',i,']=');

{$I-}readln (a[i]);{$I+}

if IoResult=0 then break;

until false;

end;

writeln ('Генерируется вектор B из ',

n,' элементов:');

randomize;

for i:=1 to n do begin

b[i]:=random*10;

write (b[i]:8:2);

end;

la:=0;

lb:=0;

s:=0;

writeln;

writeln ('Вектор c=A+B:');

for i:=1 to n do begin

c[i]:=a[i]+b[i];

write (c[i]:8:2);

la:=la+sqr(a[i]);

lb:=lb+sqr(b[i]);

s:=s+a[i]*b[i];

end;

writeln;

writeln ('Длина вектора A: ',

sqrt(la):8:2);

writeln ('Длина вектора B: ',

sqrt(lb):8:2);

writeln ('Скалярное произведение:',s:8:2);

reset (input); readln;

end.

Думаю, при анализе листинга вы обратили внимание еще на одну особенность программы -- на каждом шаге цикла ввода вектора a дополнительно выполняется цикл repeat...until, предназначенный для контроля правильности ввода элементов массива. Подробнее такие конструкции, называемые кратными циклами, будут изучены в гл. 16.

2. Задана выборка из n случайных чисел. Для n=100 определить математическое ожидание mx и дисперсию dx выборки по формулам: , .

Две подсчитываемые величины -- самые распространенные статистические характеристики набора случайных данных. Фактически, математические ожидание характеризует арифметическое среднее данных выборки, а дисперсия -- среднеквадратичное отклонение данных от среднего значения. Для хранения данных используем массив x из 100 элементов, сами данные сгенерируем из случайных чисел, находящихся в диапазоне от -1 до 1 включительно. Поскольку алгоритм накопления суммы предполагает последовательное и однократное использование каждого элемента массива, в цикле генерации элементов массива могут быть подсчитаны значения и , которые затем позволят найти mx и dx.

const n=100;

var x:array [1..100] of real;

s,d:real;

i:integer;



begin

writeln;

writeln ('Массив x[100]:');

randomize;

s:=0; d:=0;

for i:=1 to n do begin

x[i]:=random*2-1;

write (x[i]:8:3);

s:=s+x[i];

d:=d+sqr(x[i]);

end;

s:=s/n; {теперь в s - мат. ожидание,}

d:=d/(n-1)-sqr(s)/(n*(n-1));

{а в d - дисперсия}

writeln;

writeln ('s=',s:8:4);

writeln ('D=',d:8:4);

reset (input); readln;

end.

3. Объединить 2 упорядоченных по возрастанию массива A и B в массив C.

Для решения этой задачи тоже достаточно одного прохода по массивам. Действительно, заведя для каждого из массивов a, b и c по собственному счетчику (обозначим их ia, ib и i соответственно), мы можем, в зависимости от истинности или ложности соотношения aia≤bib переписывать в элемент ci значение aia или bib. Остается проконтролировать, чтобы ни один из счетчиков не вышел за границу размерности своего массива.
Читать далее...
комментарии: 0 понравилось! вверх^ к полной версии
Стальные двери 01-10-2009 13:52


«Компания Завод Спецоборудование» - Клинское производство стальных дверей.
Надежные изделия, предназначенные для первоклассной защиты, но при этом изготовитель не забывает и о этической стороне вопроса - о дизайне.
Изготовление дверей любой сложности с учетом пожеланий заказчика и технических особенности помещения. Вы можете ознакомиться с общими принципами изготовления стальных дверей прямо на главной странице сайта производителя.
Специальное предложение на время непростой экономической ситуации - скидка на всю продукцию!
стальные двери
комментарии: 0 понравилось! вверх^ к полной версии
Мужские часы 01-10-2009 13:42


Швейцарские мужские часы поражают своим дизайном и качеством. Надежные и точные, часы для настоящих мужчин. Мужские часы фирмы “Traser” – часы, отличающиеся высокой степенью надежности, характерны своими техническими и дизайнерскими особенностями, водонепроницаемые, с сапфировым и минеральным стеклом, которое не боится царапин. А тритиевая подцветка дополняет всю композицию мужественности, так как она светит всегда и её не надо подзаряжать на свету, кожаные, металлические и синтетические браслеты на выбор. Такие часы прошли проверку в экстремальных условиях, будьте уверены швейцарские часы долговечны и неприхотливы, а кроме того выглядят безупречно. Дизайн, вселяющий надежность и стиль его обладателя, сумеет воплотить его мечту о качестве и надежности такого вида устройств. Кроме того, часы были протестированы бойцами спецподразделений, дайверами и спортсменами, часы устояли перед всеми испытаниями и сохранили свой первозданный вид надолго. Швейцарские часы говорят сами за себя, а о качестве судите сами.
Если не привязываться к военной тематике. то все часы относятся к стилю Casual, т.е. добротные часы для мужчин на все случаи жизни.
Стоит обратить внимание, что все модели - это не модные сегодня подделки. Многие модели официально сертифицированы для использования в Армии, ВВС и спецвойсках США и Великобритании. Общей "фишкой", кроме противоударных титановых, стальных или карбоновых корпусов и нецарапающихся и небликующих сапфировых стеклах на цифарблатах можно считать тритиевую подстветку стрелок и символов. Такая подсветка "работает" в течение 10 лет без изменения яркости и без какой-либо подзарядки.
Другую информацию для постов можно найти на сайте.
Мужские часы
комментарии: 0 понравилось! вверх^ к полной версии
Мужчины тоже плачут? 01-10-2009 13:40


Мужчины тоже плачут?
Хм, отличный вопрос. Ну, плачут, конечно. Другой вопрос - насколько часто и насколько мужчинам это свойственно. По сути, наверное, несвойственно. Но нельзя же, с другой стороны, всё в себе всю жизнь хранить, надо хоть когда-то давать эмоциям прогуляться. В общем, много мыслей по этому поводу вы прочитаете, перейдя по ссылке, данной выше. Интересная тема, жизненная.
комментарии: 0 понравилось! вверх^ к полной версии
мобильные телефоны 30-09-2009 22:47


Огромный каталог мобильных телефонов!
Здесь вы можете выбрать аппарат с любыми, угодными вашему вкусу, характеристиками. Удобная система поиска поможет вам с этим.
Заказ можно осуществить по телефону, переговорив с продавцом, либо прямо на сайте.
Ознакомьтесь с каталогом прямо сейчас, не упустите специальные предложения :)
купиить хороший мобильный телефон в Минске
комментарии: 0 понравилось! вверх^ к полной версии
Банк курсовых 30-09-2009 22:42


Огромный ресурс по предоставлению научных работ (рефератов, курсовых, дипломов).
Вы можете выбрать уже готовую работу, а можете заказать проект специально для себя. В любом случае её разработчиком будет высококлассный специалист. Каждая работа выполняется с учетом указаний и пожеланий клиента. Опыт работы - 12 лет. Не теряйте времени, уделите свое внимание сложному вопросу образования прямо сейчас.
продажа дипломных работ
комментарии: 0 понравилось! вверх^ к полной версии
САМЫЙ большой в Рунете банк 30-09-2009 22:34


САМЫЙ большой в Рунете банк готовых курсовых, дипломных, контрольных работ, рефератов, эссе.
Учение, разумеется, свет. Но бывают в жизни студента ситуации, в которых это самое учение никак не попадает в реку деятельности. Такие ситуации весьма неприятны, но и их можно решить, обратившись за нужным материалом сюда. Поищите уже готовую работу на ваше тему, либо закажите новую, специально для себя. Не теряйте время, начните действовать уже сейчас и всё получится :)
банк рефератов и курсовых работ
комментарии: 0 понравилось! вверх^ к полной версии
Сладкий cеопультенок 30-09-2009 22:24


Cладкий Cеопультенок - конкурс со странным названием. Этим и интригует.
В действительности это соревнование оптимизаторов. Участвовать может каждый, надо только правильно себя оценить. Призовой фонд - $10 000. Заманчиво, не правда ли? Продлится этот марафон шесть месяцев, но, что самое интересное, он уже стартовал!
А теперь сопоставьте два вышеуказанных факта - участником может быть каждый, а призовой фонд не малый. Надо действовать! и не просто действовать, а действовать незамедлительно!
Cеопультенок Cладкий
комментарии: 0 понравилось! вверх^ к полной версии
Ортопедические подушки 30-09-2009 21:44


Получите всю важную информацию об ортопедических подушках прямо сейчас. Благодаря удобному интерфейсу сайта вы сможете быстро узнать ответы на вопросы по поводу беспокоящих вас и ваших близких болей в шее, спине и т.п.
Ознакомьтесь с некоторыми видами подушек здесь и здесь, чтобы получить достаточно общую информацию о подобных товарах. Выбрав нужный, сделайте заказ прямо сейчас!
магазин ортопедических подушек
комментарии: 0 понравилось! вверх^ к полной версии
Эмиграция и гражданство 30-09-2009 21:34


Ответы на все свои вопросы по поводу эмиграции и гражданства в других странах вы можете получить на emigration.cc.
На сайте хранится вся полезная информация на этот счёт. Например, можете узнать преимущества ПМЖ в интересующей вас стране, требования и процедуры для получения этого самого ПМЖ и все возможные нюансы. Для обзора предложу вам ознакомится с информацией о ПМЖ на Мальте.
Также вы можете связаться с автором сайта прямо сейчас, чтобы оставить свой запрос.
комментарии: 0 понравилось! вверх^ к полной версии