Algorytmy i struktury danych Wykład 8 Języki programowania

background image

1

Wykład VIII

Języki programowania

Algorytmy i struktury danych
Wyższa Szkoła Biznesu
Semestr III Informatyka
stosowana

background image

2

Interesuje nas

wykonywanie algorytmów

przy pomocy komputera

Naszym

największym

zainteresowaniem są jednak objęte
algorytmy przeznaczone do wykonania
przez komputery, a zatem powinniśmy
poświęcić nieco czasu na odniesienie
algorytmów

do

prawdziwych

komputerów.

background image

3

Komputer potrafi zwykle

wykonać niewielką ilość

prostych operacji

Nawet najbardziej wyrafinowany komputer jest w

rzeczywistości tylko ogromną, dobrze zorganizowaną

masą bitów i, co więcej, normalnie potrafi on wykonywać

na nich jedynie niewielką liczbę krańcowo prostych

operacji,

takich

jak

zerowanie,

przerzucanie

i sprawdzanie.
W jaki sposób przedstawiamy algorytm prawdziwemu

komputerowi i jak sprawiamy, że wykonuje on

odpowiedni proces tak, jak to zamierzono?
Powiedzmy to jeszcze bardziej bezceremonialnie. Jak

sprawiamy, że głupia maszyna o tak małych

zdolnościach w imponujący sposób realizuje nasze

subtelne i starannie opracowane algorytmy?

background image

4

Algorytmy muszą być

zapisane w jednoznaczny i

formalny sposób

Pierwszym spostrzeżeniem jest to, że nasze algorytmy

muszą być zapisane w jednoznaczny i formalny

sposób.
Zanim spróbujemy zrozumieć, w jaki sposób obracając

bitami można wypełnić proste zadanie, np. „przebiegnij

listę, dodając każdą płacę do liczby «na boku»”, musimy

zadanie to dokładnie określić odpowiadając na pytania:

– Gdzie komputer znajdzie tę listę?
– Jak ją przebiegnie?
– Gdzie znajdzie płacę i liczbę ,,na boku”? Itd.

Zadanie „przebiegnij listę” nie jest wcale wiele bardziej

dokładne i jednoznaczne niż „ubijaj białka aż do

spienienia”.

background image

5

Języki programowania,

programy, programiści

Aby opisać algorytm na użytek komputera,
posługujemy się językiem programowania, w
którym piszemy programy.
Program
to oficjalne i formalne wydanie algorytmu,
nadające się do wykonania przez komputer.
Język programowania składa się z notacji i reguł,
według których pisze się programy, a osoba pisząca
program zwie się programistą. (Ta osoba nie musi
być autorem algorytmu, na którym opiera się
program.)

background image

6

Programy wymagają

precyzyjnej składni

Język programowania wiąże się zwykle ze sztywną składnią,

dopuszczającą używanie jedynie specjalnych kombinacji wybranych

symboli i słów kluczowych.
Każda próba nadużycia tej składni może okazać się fatalna: jeśli np.

napisze się wczytaj X w języku, którego instrukcje wczytywania są

postaci

wprowadź

X,

możliwe,

że

wynikiem

będzie

bezceremonialne BŁĄD SKŁADNIOWY E5414 W WIERSZU 108. To

oczywiście wyklucza nawet tak uprzejme, ale nieprecyzyjne

żądania, jak „proszę wczytać wartość X z wejścia”.
To prawda, że uprzejme, obszerne instrukcje są przyjemniejsze dla

ludzi i być może są dla nich bardziej jednoznaczne niż ich zwięzłe i

bezosobowe odpowiedniki; jest także prawdą, że chcielibyśmy, aby

komputery były tak przychylne użytkownikowi, jak to tylko jest

możliwe. Jednakże trzeba przeciwstawić te fakty aktualnemu

brakowi zdolności rozumienia przez komputery swobodnie

mówionego (lub pisanego) języka naturalnego.

background image

7

Co zawiera formalna

składnia języka

programowania ?

Formalna składnia typowego języka programowania

zawiera:

– systematyczne warianty kilku struktur sterujących,
– systematyczne sposoby definiowania rozmaitych

struktur danych

– systematyczne wzorce podstawowych instrukcji.

Muszą one należeć do zbioru dopuszczalnych

instrukcji

stosowanego

języka

programowania,

ponieważ komputer nie wykona żadnej instrukcji,

nawet najbardziej jasnej i jednoznacznej, jeśli nie ma

jej wśród tych, które dopuszcza dany język.

background image

8

Przykład

Algorytm sumowania liczb

od 1 do N

W typowym (hipotetycznym)

języku

programowania

JP

można

by

zapisać,

jak

następuje:

wczytaj N;
X:=0;
dla Y od 1 do N wykonaj
X:=X+Y
koniec; wypisz X.

X:=0

jest

instrukcją

przypisania, która nadaje

zmiennej

X

wartość

początkową 0 (w algorytmach

zapisywaliśmy ją jako X←0).

Zwróć uwagę na słowa kluczowe

zapisane grubszą czcionką; są one

częścią składni JP
Oznacza to, że formalna definicja

składni

najprawdopodobniej

zawiera klauzulę stwierdzającą, że

jednym z poprawnych rodzajów

instrukcji w tym języku jest

instrukcja-dla,

której

ogólny

wzorzec składa się ze słowa

kluczowego

dla,

po

czym

następuje poprawny nagłówek-

dla, po czym następuje wykonaj,

po czym następuje poprawna

instrukcja, po czym następuje

koniec

background image

9

Notacja BNF (Backus-Naur

Form, od nazwisk

wynalazców)

Definicje składni można zapisać symbolicznie w notacji

zwanej BNF w następujący sposób (,,|” oznacza ,,lub”):

<instrukcja>:<instrukcja-dla>|<instrukcja-

przypisania>|...
<instrukcja-dla>:

dla <nagłówek-dla>

wykonaj

<instrukcja> koniec
Opis klauzuli nagłówka mógłby brzmieć:

<nagłówek-dla>: <zmienna> od <wartość> do

<wartość>

<wartość> można wtedy określić jako zmienną, jawnie

podaną liczbę lub jakiś inny obiekt.

background image

10

Schematyczny sposób

przedstawiania reguł

składniowych

background image

11

Schematyczny sposób

przedstawiania reguł

składniowych

background image

12

Podobnie są narzucane

wzorce definiowania

struktur danych

Np. tablicę TA o wymiarach 50 na 100, której wartości

mogą być liczbami całkowitymi, można by zdefiniować

w hipotetycznym języku JP instrukcją

definiuj TA tablica [1..50, 8..107] w niej liczby

całkowite

a język mógłby dopuścić odwołania do elementów

tablicy TA wyrażeniami postaci

TA(wartość, wartość)

Zauważ, jak określiliśmy nie tylko wymiary TA, lecz

także jej wartości indeksów; wiersze tablicy

ponumerowano 1, 2, ..., 50, ale jej kolumnom (z

jakiegoś powodu) nadano numery 8, 9, ..., 107.

background image

13

Składnia wyznacza

znacznie więcej

W rzeczywistości składnia wyznacza znacznie

więcej niż tylko dostępne struktury sterujące i

struktury danych oraz operacje elementarne.
Zwykle język ma sztywne reguły nawet w tak

drobnych kwestiach, jak poprawne ciągi symboli,

których można używać do nazywania zmiennych

lub struktur danych, i maksymalna liczba cyfr

dopuszczalna w wartościach numerycznych.
Niektóre

języki

ograniczają

długości

nazw

zmiennych do najwyżej, powiedzmy, ośmiu

symboli, z których pierwszy ma być literą alfabetu.

background image

14

Ważna jest także sprawa

interpunkcji

W językach programowania nie należy do rzadkości
wymaganie, aby po pewnych rodzajach instrukcji
następował średnik, a po innych - odstęp, aby
komentarze były ujęte w specjalne nawiasy, itd.
Biada tym, którzy do tych wymagań się nie
zastosują (dopadnie ich zapewne „choroba
średnika”).
Niedługo poznamy szczegółowy opis składni
konkretnego języka programowania, z regułami
stosowania średników i całą resztą.

background image

15

Programy wymagają

precyzyjnej semantyki

Wyposażenie języka w precyzyjną składnię stanowi

tylko część zadania stojącego przed projektantem

języka programowania.
Bez formalnej i jednoznacznej semantyki a więc bez

znaczenia

każdego

wyrażenia

dozwolonego

składniowo, składnia jest niemal bezwartościowa.
Gdyby nie podano znaczenia instrukcji, w naszym

hipotetycznym języku JP taki oto fragment programu

dla Y od 1 do N wykonaj

mógłby, oznaczać „odejmij Y od 1 i zapamiętaj wynik

w N”.

background image

16

Bez reguł semantycznych

nie poznamy

przeznaczenia instrukcji

Co gorsza, któż powiedział, że słowa kluczowe dla,

od, do itp. mają mieć coś wspólnego z ich

znaczeniem w konwencjonalnej polszczyźnie?
A może ten sam fragment programu oznacza „wyzeruj

całą pamięć komputera, zmień wartości wszystkich

zmiennych na 0, wypisz »DO DIABŁA Z JĘZYKAMI

PROGRAMOWANIA« i zatrzymaj się!”?
Któż powiedział, że „:=” oznacza „przypisz” i że „+”

oznacza „plus”? Któż powiedział, że instrukcje

wykonuje się w takiej kolejności, w jakiej są napisane?

A może „;” oznacza „po wykonaniu tego, co

następuje”, nie zaś ,,a potem wykonaj, co następuje”?

background image

17

Na szczęście w językach

znaczenia symboli są podobne do

znaczeń w języku angielskim

Oczywiście moglibyśmy odgadnąć, co to oznacza,

ponieważ projektant języka JP tak dobrał zapewne słowa

kluczowe i symbole specjalne, aby ich znaczenia były

możliwie najbardziej zbliżone do ogólnie przyjętych.
Ale komputer na podstawie takich przypuszczeń działać

nie może. Gdyby nawet mógł w jakiś sposób

wywnioskować konwencjonalne znaczenie słów i takich

symboli, jak „+”, skąd wiedziałby, bez wyraźnego

pouczenia, co zrobić z nagłówkiem pętli

dla Y od 1 do N wykonaj

gdy wartością N jest powiedzmy -314.1592?

background image

18

W poznawaniu składni i

semantyki języka wspiera

nas dokumentacja

Wydaje

się

zatem

jasne,

że

język

programowania wymaga nie tylko sztywnych
reguł

definiowania

postaci

poprawnego

programu, ale także równie sztywnych reguł
definiowania jego znaczenia.
Projektanci i producenci dostarczają jednak
szczegółową dokumentację języka, całe jej
tomy. Te podręczniki języka zawierają
bogactwo informacji dotyczących zarówno
składni, jak i semantyki.

background image

19

Przystępujemy do

kodowania

Mamy zatem język programowania JP, składnię,

semantykę i całą resztę, i właśnie skończyliśmy

opracowywanie algorytmu A rozwiązania pewnego

zadania algorytmicznego.
Przystępujemy teraz do zaprogramowania tego

algorytmu w języku JP, czynności określanej niekiedy

jako kodowanie A w JP, i chcemy przedstawić

powstały program, nazwijmy go A

P

naszemu

komputerowi.
Cóż dzieje się dalej? Odpowiedź brzmi, że w zasadzie

istnieją dwie możliwości, zależnie od tego, jakiego

języka i komputera użyjemy.

background image

20

Od algorytmu do języka

maszynowego

Program A

P

możemy wprowadzić do pamięci komputera

wystukując go na klawiaturze, wczytując z urządzenia

takiego jak dysk, odbierając z innego komputera za

pośrednictwem elektronicznego kanału komunikacyjnego lub

w jakiś inny sposób (same nośniki fizyczne i sposób ich

używania, nas tutaj nie interesują, w przeciwieństwie do

tego, co dzieje się potem).
Program A

P

przechodzi pewną liczbę przekształceń, które

stopniowo sprowadzają go „w dół” do poziomu, na którym

komputer już może sobie poradzić. Ostatecznym wynikiem

tych przekształceń jest program A

M

na poziomie maszyny

(mówi się o nim również, że jest napisany w języku

maszyny), gdyż już teraz komputer „rozumie” jego operacje

podstawowe, takie jak instrukcje manipulowania bitami.

background image

21

Języki programowania

wysokiego poziomu

Liczba przekształceń bywa różna, zależnie od języka i

komputera, ale najczęściej jest ich od dwóch do czterech.
Obiektami pośrednimi są zwykle poprawne programy w coraz

to prymitywniejszych językach programowania. Ich repertuar

struktur sterujących i struktur danych stopniowo, podobnie jak

instrukcji podstawowych, staje się coraz skromniejszy, aż

wreszcie

pozostają

jedynie

najbardziej

elementarne

możliwości działania na bitach.
Dopiero po tej ostatecznej fazie przekształceń komputer może

uruchomić (lub wykonać) pierwotny program A

M

.

Jest już dla nas teraz oczywiste, dlaczego języki takiego

rodzaju jak ten, w którym napisano pierwotny program

użytkownika A

P

, nazywają się językami programowania

wysokiego poziomu

background image

22

Przypomina to

podprogramy

Przekształcenia,

o

których

mówiliśmy

przypominają nieco zastępowanie procedur ich
treścią.
Na

instrukcję

w

języku

programowania

wysokiego poziomu można patrzeć jak na
wywołanie podprogramu lub jak na instrukcję
podstawową, która jednak dla komputera nie
jest dostatecznie podstawowa.
W konsekwencji trzeba ją uściślić i sprowadzić
do poziomu kompetencji komputera.

background image

23

Kompilacja, asembler

Pomówmy o pierwszym przekształceniu, zwanym kompilacją, w

którym program wysokiego poziomu A

P

zostaje przetłumaczony

na program A

S

w języku niższego poziomu, zwanym językiem

adresów symbolicznych lub asemblerem.
Języki adresów symbolicznych różnią się dla różnych maszyn, ale

z reguły stosuje się w nich dość proste struktury sterujące,

przypominające instrukcje skocz oraz konstrukcje jeśli-to;

operują nie tylko bitami, lecz także liczbami całkowitymi i

ciągami symboli.
Mogą one odwoływać się bezpośrednio do adresów w pamięci

komputera (ogromnego obszaru zawierającego całe stosy bitów),

mogą odczytywać spod tych adresów wszelkie zakodowane

liczby i napisy, i mogą tamże zapamiętywać kody liczb i napisów.

background image

24

Przykład (hipotetycznego)

asemblera

Typową konstrukcję pętli wysokiego poziomu:

dla Y od 1 do N wykonaj
<treść pętli> koniec

można przetłumaczyć na jej odpowiednik w języku adresów

symbolicznych:

LDS 0,Y

(załaduj stałą 0 pod adres Y)

PĘTLA POR N, Y

(porównaj wartości pod adresami N i Y)

SKR RESZTA(jeśli równe, skocz do instrukcji o etykiecie RESZTA)
DDS 1,Y

(dodaj stałą 1 do wartości pod adresem Y)

<przetłumaczona treść pętli>
SKO PETLA (skocz z powrotem do instrukcji o etykiecie PĘTLA)

RESZTA

(reszta programu)

background image

Przekształcanie

programu

wysokiego

poziomu na kod

maszynowy

Proces kompilacji, tłumaczący

programy

komputerowe

wysokiego poziomu na język

adresów symbolicznych sam

jest również wykonywany przez

program

komputerowy

(kompilator)
Proces

przekształcania

na

niższy

poziom,

w

którym

kompilacja jest pierwszą i

najbardziej

zawiłą

częścią,

ilustruje rys.
Pozostałe

kroki

tłumaczą

asembler na język maszynowy.

background image

26

Oprogramowanie

systemowe

Warto zaznaczyć, że kompilatory różnych języków

wysokiego poziomu, jakie obsługuje dany komputer,

często (choć nie zawsze) należą do dużej grupy różnych

programów dostarczanych przez producenta (komputera

bądź

systemu

operacyjnego),

zwykle

zwanych

oprogramowaniem systemowym.
Ich ogólną rolą jest ułatwianie współpracy z komputerem

na wysokim poziomie i jednoczesne odgrodzenie

użytkownika od wielu szczegółów niskiego poziomu

związanych z trybem współpracy, np. uruchomieniem

programów

napisanych

przez

użytkownika,

komunikowaniem się z innymi komputerami, sprzęganiem

się ze specjalnym wyposażeniem zewnętrznym...

background image

27

Interpretatory i

natychmiastowe

wykonanie

Jest jeszcze inny sposób, w jaki komputery wykonują

przedstawione im programy, który nie obejmuje

tłumaczenia całego programu na język niższego poziomu.
Każda

z instrukcji

wysokiego

poziomu

zostaje

przetłumaczona

na

instrukcje

poziomu

maszyny

natychmiast po jej napotkaniu, a te z kolei od razu się

wykonuje. W pewnym sensie interpreter pełni rolę

„pseudoprocesora” wykonując instrukcje wysokiego

poziomu jedną po drugiej, dokładnie tak, jak są podane.
Mechanizm odpowiedzialny za to lokalne tłumaczenie i

natychmiastowe

wykonanie

jest

też

fragmentem

oprogramowania

systemowego,

nazywanym

interpretatorem (interpreterem).

background image

28

Zalety i wady

interpretowania

programów

Podejście interpretacyjne ma pewne oczywiste zalety, m.in.

zwykle łatwiej napisać byle jaki, ale użyteczny

interpretator niż sensowny kompilator;
wykonywanie prowadzone przez interpretator pozwala na

łatwiejsze śledzenie i podsumowanie wykonania programu.

Są jednak cechy interpretacji niekorzystne w stosunku do

kompilacji
nie ma zwartego pliku wykonywalnego
trzeba rozpowszechniać kod źródłowy (trudno ochronić

prawa autorskie)
wolniejsze wykonanie (każdorazowo trzeba dokonywać

interpretacji)

background image

29

Kompilować czy

interpretować ?

To, czy komputer będzie kompilował, czy
interpretował dany program, zależy od
przeznaczenia danego programu, samego
komputera,

języka

programowania,

i

konkretnego

pakietu

oprogramowania

systemowego, którego używamy.
Niektóre języki programowania nadają się do
interpretowania bardziej niż inne, wszystkie
jednak mogą w zasadzie być kompilowane.

background image

30

Dlaczego nie

algorytmiczne Esperanto?

Od czasu, gdy we wczesnych latach pięćdziesiątych

zaczęły

pojawiać się języki programowania

wysokiego poziomu, zaprojektowano ich setki oraz

napisano dla nich kompilatory i (lub) interpretatory,

a nadal nowe języki pojawiają się jak grzyby po

deszczu.
Dlaczego? Czynie byłoby lepiej mieć jeden język

uniwersalny, takie algorytmiczne Esperanto, w

którym zapisywałoby się wszystkie algorytmy i

którego każdy mógłby się łatwo nauczyć? Skąd

taka mnogość języków? Czym się różnią ? Kto

używa których języków i w jakich celach?

background image

31

Dlaczego nie

algorytmiczne Esperanto?

Odpowiedź

Zasadniczo są dwie przyczyny tego zjawiska:

– nowe osiągnięcia sprzętowe (choć dziś w dużej

mierze udaje się uwolnić wiele języków od
bezpośredniego, ścisłego związku ze sprzętem).

– oraz nowe i zróżnicowane dziedziny zastosowań

;

Obie stwarzają zapotrzebowanie na nowe języki
programowania.

Badania

nad

językami

programowania należą do z najbardziej się
rozwijających i przyciągających powszechną uwagę
dziedzin informatyki.

background image

32

Badania nad językami

programowania

Ludzie chcą języków zarówno uniwersalnych, jak i przeznaczonych

do szczególnych zastosowań oraz ich precyzyjnej definicji i sprawnej

realizacji.
Wymyśla się wyrafinowane techniki kompilacji i tłumaczenia, proponuje

się nowe struktury sterujące i nowe struktury danych oraz wprowadza

się silne mechanizmy umożliwiające programistom definiowanie ich

własnych struktur danych.
Pożądane są języki zachęcające do dobrego stylu programowania

i wszyscy próbują zaprojektować je tak, aby zawrzeć w nich rozmaite

zalecane idee budowy algorytmów.
Badacze

interesują

się

opracowaniem

środowisk

programistycznych, czyli przychylnych użytkownikowi systemów

konwersacyjnych, pozwalających programiście pisać, redagować,

zmieniać, wykonywać, analizować, poprawiać i symulować programy.
Fascynujące badania dotyczą wizualnych języków programowania,

umożliwiających rysowanie programów zamiast ich pisania.

background image

33

Uniwersalność języków

programowania

Ostatnia nasza uwaga dotyczy uniwersalności języków

programowania.
W pewnym technicznym sensie praktycznie wszystkie języki

programowania są równoważne pod względem swojej siły

wyrazu. Każde zadanie algorytmiczne rozwiązywalne w

jednym języku jest w zasadzie rozwiązywalne również w

każdym innym języku.
Różnice między językami są pragmatyczne i dotyczą

przydatności do pewnych, zastosowań, przejrzystości,

struktury, sprawności realizacji i algorytmicznych sposobów

myślenia.
Wobec znaczących różnic między językami programowania

ten fakt może być przyjmowany jako coś niespodziewanego.


Document Outline


Wyszukiwarka

Podobne podstrony:
Algorytmy i struktury danych Wykład 1 Reprezentacja informacji w komputerze
Algorytmy i struktury danych Wykład 3 i 4 Tablice, rekordy i zbiory
Algorytmy i struktury danych Wykład 2 Typ danych,Proste typy danych
Algorytmy i Struktury Danych Wykład
Algorytmy i struktury danych Wykład 9 Metody algorytmiczne
Algorytmy i struktury danych Wykład 1 Reprezentacja informacji w komputerze
Algorytmy i struktury danych Wykład 3 i 4 Tablice, rekordy i zbiory
Algorytmy, struktury danych i techniki programowania wydanie 3
ALS - 009-005 - Program Sortowanie INSERTION SORT, Informatyka - uczelnia, WWSI i WAT, wwsi, SEM II,
wyk.9, Informatyka PWr, Algorytmy i Struktury Danych, Architektura Systemów Komputerowych, Assembler
wyk.7.1, Informatyka PWr, Algorytmy i Struktury Danych, Architektura Systemów Komputerowych, Assembl
Algorytmy i struktury danych AiSD-C-Wyklad05
ALS - 007-005a - Program drzewa BST, Informatyka - uczelnia, WWSI i WAT, wwsi, SEM II, Algorytmy i S
wyk.7, Informatyka PWr, Algorytmy i Struktury Danych, Architektura Systemów Komputerowych, Assembler
wyk.8, Informatyka PWr, Algorytmy i Struktury Danych, Architektura Systemów Komputerowych, Assembler
Algorytmy struktury danych i techniki programowania
Algorytmy i struktury danych, AiSD C Wyklad04 2
Algorytmy, struktury danych i techniki programowania

więcej podobnych podstron