Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Аверянов Основы современной информатики 2007

.pdf
Скачиваний:
72
Добавлен:
16.08.2013
Размер:
7.31 Mб
Скачать

Логические отношения:

 

 

 

 

 

Бейсик

Фортран

 

Паскаль

 

 

=

.eq.

 

=

 

 

<>

.ne.

 

<>

 

 

>

.gt.

 

>

 

 

<

.lt.

 

<

 

 

>=

.ge.

 

>=

 

 

<=

.le.

 

<=

 

 

and

.and.

 

and

 

 

or

.or.

 

or

 

Логические инструкции:

 

 

 

 

 

Бейсик

Фортран

 

 

Паскаль

10 if i>1 then i=0

if (i .gt. 1) i=0

 

if i>1 then i:=0;

20 if i>1 then i=0 else i=–1

if (i .gt.

1) then

if i>1

 

 

i=0

 

 

i:=0

 

 

else

 

 

else

 

 

i=–1

 

 

i:=–1;

30 if i>1 then i=0: j=2 else i=–1

if (i .gt. 1) then

 

if i>1 then

 

 

j=0

 

 

begin

 

 

j=2

 

 

i:=0;

 

 

else

 

 

j:=2

 

 

i= –1

 

 

end

 

 

 

 

 

end if

 

 

 

 

 

else

Циклы:

 

 

 

i:=–1

 

 

 

 

Бейсик

Фортран

 

 

Паскаль

10 for

i = 1 to n

do 10 i=1, n

 

for i:=1 to n begin

20

x = x+1

x=x+1

 

x:=x+1

30 next i

10 continue

 

 

end;

10 white i >10

do 10 idum = 1,10000

while i < 10 do

20

i=i+1

if (i .ge.

10) go to 100

begin

30 wend

i =i+1

 

 

i:= i + 1

 

 

10 continue

 

 

end;

 

 

100 continue

 

 

 

10 while idum = 0

do 10 idum = 1,10000

repeat

20

i = i + 1

i = i + 1

 

 

i:= i + 1

30 if i>=10 then goto 50

if (i .ge.

10) go to 100

until i >= 10;

40 end

 

10 continue

 

 

 

50 'имитация цикла repeat – until’

100 continue

 

 

 

181

Указанные языковые конструкции являются общими для всех традиционных (императивных) языков программирования. На этом уровне различия в языках нельзя считать принципиальными. В качестве примера использования перечисленных средств программирования (как начального уровня) представлены тексты программ на языках FORTRAN, PASCAL и С, и блок-схема программы определения максимального и минимального элементов массива

(рис. 5.3).

 

 

 

 

Начало

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ввод an, n

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

i = 1

 

 

 

 

 

 

 

 

 

 

 

numax = 1

 

 

 

 

 

 

 

 

 

 

 

 

numin =1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ДА

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ai > a (numax)

 

numax=i

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

НЕТ

ДА

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ai < a (numin)

 

 

 

 

 

 

 

 

 

 

 

numin=i

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

НЕТ

 

 

 

 

 

НЕТ

 

 

 

 

i > n

ДА

Вывод a (numax)

a(numin) END

Рис. 5.3. Блок-схема программы, определяющей максимальный и минимальный элементы массива

182

Фортран:

PROGRAM MINMAX real a(100)

integer n, numax, numin, i print *,’ input n’

read *,n

do 10 i= 1, n

print *, ‘input a( ‘.i.’)’ read *,a(i)

10 continue numax=1 numin=1 do 20 i=2, n

if (a(i).gt.a(numax) ) numax= i if (a(i).It.a(nuinin ) ) numin=i

20continue

print *, ' max{a(i)}=’,a(numax),’ min{a(i)}=’ ,a(numin) end

Паскаль:

program extrem( input, output); var

n , i , nuimax, numin : integer ; a: array [ 1..100 ] of real; begin

writeln( ‘ input n ‘) ;readln(n) ; for i:=1 to n do

begin

writeln( ‘ input a(‘.j.’ ) ‘);readIn (a [ i ] ); end ;

numax: = 1; numin : = 1; for i: =2 to n do

begin

if a[ i ]> a[numax] then numax:=i; if a[ i ]< a[numin] then numin :=i; end;

writeln(' max{a(i)}=’,a[numax],’ min{a(i)}=’ ,a[numin]); end.

Си:

# include<stdio. h >

int n , i ,numax,numnin ; float, a[100];

main( )

{

183

printf("input n\n" ) ; scanf(" %g ", &n ); for( i = 0; i <n; i++)

{

printf("input a(%d)\n", i ); scanf("%g",&a[i ]);

}

numax=numin=0; for( i=1;i<n;i++)

{

if (a[ i ] > a[numax])numax=i ; if (a[ i ] < a[numin] )numin=i;

}

printf( "max{a( i ) }=%g min{a( i)}=%g" ,a[numax] ,a[numin] ) ;

}

В основе создаваемых языков, как правило, лежит некоторая основополагающая идея или, как говорят теоретики программирова-

ния, парадигма.

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

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

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

184

мами (рис. 5.4). Модули, собранные по определенной тематике – математические, графические, экономические и т.п., объединяются в библиотеки.

Основная программа

Внешние подпрограммы

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

На первом этапе такие модули в объектном виде включались в виде внутренних библиотек в транслятор языка и подключались на уровне компоновки в исполнимую программу. К ним относились продпрограммы – функции для вычисления наиболее распространенных математических функций (тригонометрических, логарифмов, MIN, MAX и т.п.). Затем средства разработки этих модулей были включены в стандарт языка, и разными фирмами было разработано большое количество внешних подпрограмм для различных приложений. Так, фирма IBM разработала библиотеку научных подпрограмм на Фортране, в которую были включены практически все разделы вычислительной математики. В России была разработана библиотека графических подпрограмм на Фортране (ГРАФОР). Кроме этого в различных организациях было создано большое количество узкоспециализированных библиотек.

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

185

Такой подход позволяет:

1)сократить текст основной программы путем включения дополнительных (внешних) модулей на уровне компоновки (иногда многократного включения одних и тех же модулей на различных фазах выполнения программы);

2)распараллеливать выполнение проекта, распределяя работу между программистами;

3)структурировать программу, облегчая ее тестирование и поиск ошибок.

Этот подход при проектировании сложных систем называется восходящим проектированием (или проектированием снизу вверх).

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

Фортран включает три структуры, использующие указанные принципы.

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

Name(arg) = EXPRESSION

где Name – имя оператора функции; arg – список формальных параметров; EXPRESSION – само выражение.

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

выражение:

ах2 + by2 + cxy + d

Его можно оформить, как оператор функцию.

QUAD(X,Y)=A*X**2+B*Y**2+C*X*Y+D

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

186

Так, например:

RESULT=X4+200*QUAD(X1,Y1)+300*QUAD(X2,Y2)+400*QUAD(X3,Y3)

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

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

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

t FUNCTION f(a1,a2…an)

t – тип функции, может быть: Integer, Real, Double Precision,

Сomplex, Logical; по умолчанию Real или Integer определяется первой буквой имени функции; FUNCTION – ключевое слово; f – имя функции; a1,a2, …, an – имена формальных параметров.

Структура этой подпрограммы следующая: FUNCTION Name(a1, a2, …, an)

исполнимая

часть

Name=Result

Return

End

После выполнения основной (исполнимой) части имени функции присваивается значение полученного результата ее работы (Result). Оператор Return передает результат в вызывающую программу (End – указание транслятору о завершении текста подпрограммы при трансляции).

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

187

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

В качестве примера рассмотрим подпрограмму функции для скалярного произведения двух векторов X и Y.

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

n

S = ∑ Xi·Yi

i=1

FUNCTION SKALAR(X,Y,N)

DIMENSION X(100),Y(100) s=0.0

do 1 i=1,N s=s+X(i)*Y(i)

l Continue SKALAR=s RETURN

END

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

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

188

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

Программа SUBROUTINE оформляется следующим образом:

SUBROUTINE S(a1,a2, …, an)

Тело подпрограммы Исполнительная часть

RETURN

END

где SUBROUTINE – ключевое слово; S – имя подпрограммы (не имеет типа и никак не связано с входными и выходными параметрами); a1,a2, …, an – формальные параметры, используемые при работе подпрограммы, включая и выходные параметры (результаты вычислений). Формальные и фактические параметры должны быть согласованы между собой (так же, как и в подпрограмме функции) по типу, количеству и порядку следования. Естественно выходные (вычисляемые) параметры фигурируют в главной программе только в виде имен (не имеющих значений до начала работы модуля). RETURN и END – выполняют те же функции, что и в подпрограмме функции.

В качестве примера использования SUBROUTINE рассмотрим математический алгоритм перемножения матрицы на вектор.

SUBROUTINE MATRIX(A,X,Y,N)

DIMENSION F(50,50),X(50),Y(50) DQ 2 I=1,N

s=0.0 DQ1 I=1,N

s=s+A(I,J)*X(j)

Y(I)=s

RETURN END

189

В данном случае значения всех параметров передаются из главной программы, и в результате работы этой SUBROUTINE в главную программу возвращается вычисленное значение вектора Y(I).

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

CALL(a1,a2, …, an)

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

Следующее направление в развитии языков программирования (парадигма программирования) обычно связывают с так называе-

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

Появление парадигмы структурного программирования обычно связывается с разработкой Никлаусом Виртом языка Pasсal в 1972 г. Основное назначение этого языка изначально связано с обучением студентов программированию. Следует отметить, что Вирт – одна из ключевых фигур в создании программистской идеологии. Он разработал также такие языки, как Modula, Oberton, Object Pascal. Справедливости ради необходимо отметить, что большую популярность Pasсal приобрел благодаря очень удачной среде Turbo Pascal, разработанной фирмой Borland. При этом стандарт «оригинального» языка значительно расширен фирмой. Что же касается структурного программирования по отношению в языку Pasсal, то здесь можно выделить несколько основных элементов,

190