Отправляет email-рассылки с помощью сервиса Sendsay

Pascal с нуля by [CPM]

  Все выпуски  

Pascal с нуля by [CPM] Выпуск №13


Информационный Канал Subscribe.Ru

[Ø] Рассылка "Pascal с нуля" by [CPM]. Выпуск №13 [Ø]

::[Ø]BEGIN[Ø]::

Автор: v()v@#[CPM] mailto: vovanc@bigmir.net

Автор: MedL[CPM] mailto: medlmail@bigmir.net

Автор: Light[CPM] mailto: lightcpm@bigmir.net

Доброе время суток, уважаемые подписчики!!


Сегодня у нас речь пойдёт о такой фишке, как процедуры. Сначала я опубликую домашнее задание. А вообще, это очень серьёзная тема, изучив которую вместе со следующей, вы будете чувствовать себя более уверенными в своих силах. А пока смотрите домашнее задание. Его в основном делал Light[CPM], потому что мне прислали свои решения только человека, из которых только двое прислали исходники. А что остальные? Все решения я привожу без каких-либо комментариев, потому-что это очень легко. Будет лучше для вас, если вы разберётесь с этим сами.
№1 by MedL



uses crt;
var
a: array[1..5, 1..6] of integer;
b , j ,i: integer;
begin
clrscr;
randomize;
for j:=1 to 5 do begin
  b:=0;
  for i:=1 to 6 do begin
    a[j,i]:=random(50);
    b:=(b+a[j,i]);
    if not(i=6) then write(a[j,i]:5) else
    begin write(a[j,i]:5);
      writeln(b:12);
    end;
  end;
end;
writeln;
for i:=1 to 6 do begin
  b:=0;
  for j:=1 to 5 do
  b:=a[j,i]+b;
  write(b:5);
end;
readln;
end.

№2



uses crt;
var
a:array[1..7,1..7] of integer;
b:array[1..2,1..7] of integer;
i,j,l,m:byte;
s:integer;
BEGIN
clrscr;
textbackground(black);
textcolor(15);
Randomize;
for i:=1 to 7 do
begin
  for j:=1 to 7 do
  begin
    a[i,j]:=random(151)+100;
    write(a[i,j],' ');
  end;
  writeln;
end;
for i:=1 to 7 do
begin
  s:=0;
  for j:=1 to 7 do s:=s+a[i,j];
  b[1,i]:=s;
end;
for j:=1 to 7 do
begin
  s:=0;
  for i:=1 to 7 do s:=s+a[i,j];
  b[2,j]:=s;
end;
gotoxy(9,20);
for m:=1 to 7 do write('N':5,m);
writeln;
for l:=1 to 2 do
begin
  if l=1 then write('Stroka :');
  if l=2 then write('Stolbec :');
  for m:=1 to 7 do write(b[l,m]:6);
  writeln;
end;
gotoxy(31,12);
textcolor(26);
write('<<Press ANY Key>>');
gotoxy(72,23);
textcolor(15);
write('By Light');
readkey;
END.

№3



uses crt;
var
a:array[1..7,1..7] of integer;
i,j,flag:byte;
temp:integer;
BEGIN
clrscr;
textbackground(black);
textcolor(15);
write('Start-Massive');
writeln;
Randomize;
for i:=1 to 7 do
begin
  for j:=1 to 7 do
  begin
    a[i,j]:=random(101)+150;
    write(a[i,j],' ');
  end;
  writeln;
end;
gotoxy(31,13);
write('<<Press ANY Key>>');
readkey;
writeln;
write('Sorted Massive');
writeln;
repeat
  flag:=1;
  for i:=1 to 7 do
    for j:=1 to 6 do
      if a[i,j]>a[i,j+1] then
      begin
        temp:=a[i,j+1];
        a[i,j+1]:=a[i,j];
        a[i,j]:=temp;
        flag:=0;
      end;
until flag=1;
for i:=1 to 7 do
begin
  for j:= 1 to 7 do write(a[i,j],' ');
  writeln;
end;

gotoxy(31,13);
textcolor(26);
write('<<Press ANY Key>>');
gotoxy(72,24);
textcolor(15);
write('By Light');
readkey;
END.

№4



uses crt;
var
a:array[1..7,1..7] of integer;
i,j,flag:byte;
temp:integer;
BEGIN
clrscr;
textbackground(black);
textcolor(15);
write('Start-Massive');
writeln;
Randomize;
for i:=1 to 7 do
begin
  for j:=1 to 7 do
  begin
    a[i,j]:=random(101)+150;
    write(a[i,j],' ');
  end;
  writeln;
end;
gotoxy(31,13);
write('<<Press ANY Key>>');
readkey;
writeln;
write('Sorted Massive');
writeln;
repeat
  flag:=1;
  for i:=1 to 7 do
    for j:=1 to 6 do
      if a[i,j]<a[i,j+1] then
      begin
        temp:=a[i,j+1];
        a[i,j+1]:=a[i,j];
        a[i,j]:=temp;
        flag:=0;
      end;
until flag=1;
for i:=1 to 7 do
begin
  for j:= 1 to 7 do write(a[i,j],' ');
  writeln;
end;

gotoxy(31,13);
textcolor(26);
write('<<Press ANY Key>>');
gotoxy(72,24);
textcolor(15);
write('By Light');
readkey;
END.

№5



uses crt;
var
a:array[1..5,1..5] of integer;
i,j:byte;
BEGIN
clrscr;
textbackground(black);
textcolor(15);
Randomize;
for i:=1 to 5 do
begin
  for j:=1 to 5 do
  begin
    a[i,j]:=random(9);
    write(a[i,j],' ');
  end;
  writeln;
end;
writeln;
for i:=5 downto 1 do
begin
  for j:=1 to 5 do write(a[j,i],' ');
  writeln;
end;
gotoxy(31,13);
textcolor(26);
write('<<Press ANY Key>>');
gotoxy(72,24);
textcolor(15);
write('By Light');
readkey;
END.



Начинаем нашу работу.


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



...
WriteLn(a+b);
ReadLn;
...
WriteLn(a+b);
ReadLn;
...

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



...
Procedure sum(a,b:integer);
begin
a:=a+b;
writeln(a);
readln;
end;
...
sum(х,у);
...

После выполнения команды sum(х,у);, на экран будет выведена сумма значений переменных х и у, и программа "замрёт в ожидании" нажатия на Enter.
Рассмотрим общую структуру процедур:



procedure name(parametr1:type1;parametr2,parametr3:type3);
var
local1:type;
...
begin
operator1;
operator2;
...
end;

Из данного описания следует:
1) Каждая процедура должна начинаться со служебного слова Procedure.
2) После этого должно следовать имя процедуры и список (не обязательно) передаваемых параметров (в круглых скобках).

Давайте подробней рассмотрим нашу процедуру суммирования. Первая команда там - a:=a+b;, которая увеличивает переменную, а на значение переменной b.
Мы передаём в процедуру значения переменных х и у в данном случае, при чём после отработки процедуры значения переменных не изменятся. Мы можем в нашей программе, используя данную процедуру написать sum(5,10);, результатом будет вывод на экран числа 15.
Как в первом так и во втором случае процедуре передавалось значение переменной. Этот способ передачи параметров называется передачей по значению.

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

Все переменные, которые объявлены в "заголовке" программы, могут быть использованы любой процедурой данной программы. Такие переменные называются глобальными.

Передача параметров по значению - самый элементарный способ передачи параметров. Несколько особенностей:
1) При вызове подпрограммы, в стеке (место в памяти, но о нём чуть позже) создаётся локальная переменная, которая получает значение параметра, указанного в вызове подпрограммы (будь то процедура или функция).
2) При изменении значения какого-либо параметра в нашей подпрограмме, все изменения происходят в области стека, но не в области переменных. Это означает, что если мы передаём в качестве параметра переменную, то при выполнении каких-либо действий над локальными переменными в теле подпрограммы, её значение не меняется.
Это значит, что если мы вызовем нашу процедуру sum таким способом:



...
var
x,y:integer;
begin
x:=55;
y:=20;
sum(x,y);
...

Значения переменных Х и У, которые "попадают" в соответствующие локальные переменные a и b, не изменятся, о чём я уже упоминал выше.

Есть одна тонкость при передачи массива по значению, даже не одна, а две:
1) Если вы напишете что-то типа этого:

procedure myMas(a:array[1..10] of integer);

Произойдёт ошибка Error 12: Type identifier expected - это нам говорят, что мы не указали тип данных, которые передаём. Но как же передать массив? Ответ: сделать свой тип, что будет выглядеть примерно так:



type
ArrCPM = array[1..10] of integer;
...
Procedure myMas(a:ArrCPM);
...

2) Стек не резиновый. Поэтому если вы передаёте массив по значению, то в стеке создается такой же локальный массив. Если вы передаёте большой массив, или не очень большой, но с присутствием большого кол-ва вложений, то произойдёт ошибка переполнения стека (Stack overflow error). Также при передаче массива идёт поэлементное копирование массива в стек, что может привести к потере производительности.

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



...
Procedure hello(var x,y:byte; z:integer);
...

Тут мы передаём два параметра (х и у) по ссылке и один параметр(z) по значению.
Этот способ подразумевает передачу параметров как из программы в подпрограмму, так и из подпрограммы в программу. То есть мы можем заставить подпрограмму вернуть какой-либо результат своих действий.
Рассмотрим пример:



...
var L:real;
...
Procedure radian(var alfa: real);
begin
alfa:=alfa*pi/180;
end;
...
L:=180;
radian(L);
write(sin(L));
...

В данном случае мы передаем подпрограмме адрес на ячейку памяти, где лежит переменная L. Все изменения локальной переменной alfa предполагают изменение переменной L, которую мы передаём. То есть мы, передавая как параметр по ссылке переменную L со значением 180, после выполнения процедуры получаем в этой переменной значение Pi (3.14...). Потом мы выводим синус угла 180 градусов. Должно вывести "0" на экран, что означает, что в L действительно лежит значение Pi.

Узнав о передаче параметра по ссылке, мы можем сделать вывод: массивы лучше передавать по ссылке. Написав так:



type
ArrCPM = array[1..10] of integer;
...
Procedure myMas(var a:ArrCPM);
...

Таким образом, при передаче данного массива по ссылке происходит загрузка в область стека не 21 байта, а 4 байтов адреса массива в области данных (2 байта - сегмент, 2 - смещение), это даёт прирост в производительности.

Также следует отметить, что при данном способе передачи параметров в процедуру нельзя "запихнуть" константу или выражение. Это приведёт к ошибке.

Очень часто меня спрашивают: Почему процедура Delay из модуля Crt даёт на разных компьютерах разное значение?
Это по тому, что она очень коряво написана. Поэтому я предпочитаю юзать собственную процедуру для этого. Дело в том, что у нас есть системный таймер, который увеличивает значение, которое находится по адресу $40:$6c в памяти каждого компьютера на единицу примерно 18.2 раза в секунду. Напишем на основе этого процедуру, которая будет давать задержку.



Procedure Stop(x:longint);
var
SystemTime: longint absolute $40:$6c; {связываем переменную с адресом
в памяти. Каждый раз, когда мы используем эту переменную, мы фактически
обращаемся к ячейке в памяти, то есть при изменении переменной меняеться значение
в памяти. Не рекомендуется менять это значение, это приведёт к интересным последствиям}
begin
inc(x,SystemTime); {тут мы делаем увеличиваем х на значение таймера.}
repeat until x<=SystemTime;{Не думайте, что этот цикл будет выполняться
вечно. Ведь у нас переменная SystemTime связана с ячейкой памяти которая примерно каждые
55 мсек увеличивает своё значение на 1. То есть, когда это значение обновиться х раз
произойдёт выход из цикла.}
end;

Если мы напишем в программе строку типа Stop(18);, у нас произойдёт задержка ,примерно, на 1 сек. Я советую забить эту процедуру в свой модуль, как это сделал я. Как это сделать вы узнаете позже.

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

На этом всё. Ответы шлите на ящик. Вопросы тоже туда.
Или на форум http://studcity.ru/forum/viewforum.php?f=10 .

::[Ø]END[Ø]::


Дизайнерское слово Ustasа

Автор: Ustas[CPM] mailto: Ustas1715@yandex.ru

 "Rape me, rape me my friend,
   rape me, rape me again…."
           Nirvana(про наш дизайн)

Приветствую Вас!
Недавно ночью я заново взялся перерабатывать дизайн под нестареющую Нирвану. Думаю, так воспринимать написанное будет ещё легче. Кстати это наша официальная эмблема [Ø]. А почему - догадайтесь сами. Подсказку ищите в названии нашей команды.

  

Наша команда [CPM]:

Дизайн, верстка и корректировка>>> Ustas[CPM]

Пишет >>> v()v@#[CPM]
ICQ:88880172

Тоже Пишет >>> MedL[CPM]ICQ:88883515

Пишет(новенький) >>> Light[CPM]

 

© 2004 Kiev Ukraine [CPM] Group 


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу


В избранное