DZWON

Są tacy, którzy czytają tę wiadomość przed tobą.
Zapisz się, aby otrzymywać najnowsze artykuły.
E-mail
Imię
Nazwisko
Jak chcesz przeczytać The Bell
Bez spamu

Programowanie strukturalne Jest metodą tworzenia ulepszonych programów. Służy do organizowania projektowania i kodowania programów w taki sposób, aby zapobiec większości błędów logicznych i wykryć te, które są popełniane.

Używając języka wysokiego poziomu (takiego jak Fortran), programiści mogli pisać programy o długości do kilku tysięcy linii. Jednak język programowania łatwo zrozumiały w krótkich programach staje się nieczytelny (i niemożliwy do zarządzania) w przypadku dużych programów. Pozbycie się takich niestrukturalnych programów nastąpiło wraz z utworzeniem ustrukturyzowanych języków programowania w 1960 roku. Należą do nich języki Algol, Pascal i S.

Programowanie strukturalne implikuje dobrze zdefiniowane struktury sterujące, bloki programowe, brak instrukcji GOTO, samodzielne procedury obsługujące rekursję i zmienne lokalne. Najważniejszą rzeczą w programowaniu strukturalnym jest możliwość podzielenia programu na jego elementy składowe. Używając programowania strukturalnego, przeciętny programista może tworzyć i obsługiwać programy o długości ponad 50 000 linii.

Programowanie strukturalne jest ściśle związane z takimi pojęciami, jak „projektowanie odgórne” i „programowanie modułowe”.

Metoda projektowania odgórnego zakłada sekwencyjną dekompozycję funkcji przetwarzania danych na proste elementy funkcjonalne („odgórne”).

W rezultacie budowany jest hierarchiczny schemat, który odzwierciedla kompozycję i podporządkowanie poszczególnych funkcji, czyli tzw struktura funkcjonalna algorytmu(FSA).

Struktura funkcjonalna algorytmu aplikacji jest rozwijana w następującej kolejności:

1) określono cele automatyzacji obszaru tematycznego i ich hierarchię;

2) ustala się skład wniosków (zadań procesowych) zapewniający realizację celów;

3) wyjaśniono charakter zależności między aplikacjami i ich główne cechy (informacje dotyczące rozwiązywania problemów, czas i częstotliwość rozwiązań itp.);

4) określono funkcje przetwarzania danych niezbędne do rozwiązywania problemów;

5) funkcje przetwarzania są rozłożone do wymaganej złożoności strukturalnej, realizowanej przez proponowany zestaw narzędzi.

Taka struktura aplikacji odzwierciedla to, co najważniejsze - skład i wzajemne powiązania funkcji przetwarzania informacji dla realizacji aplikacji, chociaż nie ujawnia logiki wykonywania poszczególnych funkcji, warunków czy częstotliwości ich wywołań.

Dekompozycja musi być noszona ściśle funkcjonalny charakter, tj. należy opisać oddzielny element FSA pełna znacząca funkcja przetwarzanie informacji, które zakłada określony sposób implementacji na poziomie oprogramowania.


Programowanie modułowe oparty na koncepcji modułu logicznie połączony zestaw elementów funkcjonalnych, zaprojektowanych w postaci oddzielnych modułów oprogramowania. Programowanie modułowe omówiono w rozdziale 7.

Programowanie strukturalnepolega na uzyskaniu poprawnego programu z kilku prostych struktur logicznych. Opiera się na sprawdzonym twierdzeniu o strukturze, które stwierdza, że \u200b\u200bkażdy poprawny program (z jednym wejściem, jednym wyjściem, bez pętli i nieosiągalnych instrukcji) może być napisany przy użyciu tylko następujących podstawowych struktur logicznych:

· Liniowy (następujący);

· Nieliniowe (widelec);

· Cykliczne (cykl lub powtórzenie).

To twierdzenie zostało sformułowane w 1966 roku przez Boima i Jacopiniego (Corrado Bohm, Guiseppe Jacopini). Główną ideą twierdzenia jest przekształcenie każdej części programu w jedną z trzech podstawowych struktur lub ich kombinację, tak aby zredukować nieustrukturyzowaną część programu. Po wystarczającej liczbie takich przekształceń pozostała niestrukturalna część zniknie lub stanie się niepotrzebna. Twierdzenie dowodzi, że wynik jest programem równoważnym z pierwotnym i wykorzystującym tylko wyżej wymienione podstawowe struktury.

Kombinacje poprawnych programów uzyskane przy użyciu tych trzech podstawowych struktur są również poprawnymi programami. Poprzez iterację i zagnieżdżanie podstawowych struktur można uzyskać program o dowolnej wielkości i złożoności. Używając tylko określonych struktur, nie ma potrzeby bezwarunkowych skoków i etykiet. Dlatego czasami kodowanie strukturalne jest rozumiane w wąskim znaczeniu jako programowanie bez „GOTO”.

W języku algorytmicznym C (C ++) do implementacji kodowania strukturalnego używane są następujące operatory:

· Operator złożony;

· Wyrażenie operatorowe;

· Wybór operatora;

· Operator z etykietą;

· Zmiana operatora;

· Iteracja operatora;

Operator Asm;

· Deklaracja (tylko w C ++).

Śledź strukturę(Rys. 5.1, a) jest implementowana przez operator złożony, operator wyrażenia, operator asm itp.

Operator złożonylub blok to lista (prawdopodobnie pustych) instrukcji ujętych w nawiasy klamrowe {…} ... Składniowo blok jest traktowany jako pojedyncza instrukcja, ale wpływa na kontekst identyfikatory w nim zadeklarowane. Bloki można zagnieżdżać na dowolnej głębokości.

Operator wyrażenia jest wyrażeniem, po którym następuje średnik. Jego format jest następujący:

<выражение>;

Kompilator C ++ wykonuje instrukcje wyrażeń, oceniając wyrażenia. Wszystkie skutki uboczne tego obliczenia są zakończone przed wykonaniem następnej instrukcji. Większość instrukcji wyrażeń to albo instrukcje przypisania, albo wywołania funkcji (np. Printf (), scanf ()). Jest to szczególny przypadek pusty operatorskładający się z jednego średnika ( ; ). Pusta instrukcja nie powoduje żadnego działania. Jest to jednak przydatne w przypadkach, gdy składnia C ++ wymaga jakiegoś operatora, ale program go nie potrzebuje (na przykład nieskończona pętla for).

Operatory Asm zapewniają programowanie na poziomie zespołu (użycie wskaźników, operacje bitowe, operacje przesunięcia itp.). Używając języka asemblera do obsługi krytycznych sytuacji, powtarzających się operacji, możesz poprawić szybkość optymalizacji bez żadnych ulepszeń języka wysokiego poziomu.

Struktura wideł (Rys. 5.1, b, c) jest realizowane przez operatory selekcji. Operatory wyboru lub instrukcje sterowania przepływem, dokonują wyboru jednej z alternatywnych gałęzi programu, sprawdzając określone wartości. Istnieją dwa typy instrukcji select: if ... else i switch.

Podstawowe oświadczenie if(Rysunek 5.1, b) ma następujący format:

if (conditional_expression) operator_if_ "prawda" operator_if_ "false";

Język C ++, w przeciwieństwie na przykład do języka Pascal, nie ma specjalnego typu danych logicznych. W sprawdzeniach warunkowych ten typ może być odtwarzany przez zmienną całkowitą lub wskaźnik do typu. Conditional_expression musi być zapisany w nawiasach. To wyrażenie jest oceniane. Jeśli jest null (lub pusty w przypadku typu wskaźnikowego), mówimy, że warunkowe_wyrażenie fałszywie(fałszywe ) ; inaczej to zaiste(prawdziwe).

Jeśli nie ma klauzuli else, a wyrażenie conditional_expression daje w wyniku „prawda”, wykonywana jest instrukcja_jeśli_ „prawda”; w przeciwnym razie jest ignorowany.

Jeśli wydano wyrok operator_if_ ma wartość „false”, a conditional_expression zwraca wartość „true”, a następnie operator_if_ ma wartość „true”; w przeciwnym razie operator-if ma wartość false.

Konwersje wskaźników są wykonywane w taki sposób, że wartość wskaźnika można zawsze poprawnie porównać z wyrażeniem o stałej typu dającej 0. Zatem porównanie dla wskaźników zerowych można wykonać jako:

if (! ptr) ... lub if (ptr \u003d \u003d 0) ....

Operator_if_ "false" i operator_if_ "true" mogą same w sobie być instrukcjami if, co pozwala na zorganizowanie dowolnej głębokości zagnieżdżania sprawdzeń warunkowych. Używając zagnieżdżonych instrukcji if ... else, upewnij się, że właściwy wybór wykonywalne operatory. Wszelkie niejednoznaczności w konstrukcji „else” są rozwiązywane przez porównanie else z ostatnim znalezionym na poziomie this if block bez else.

Na przykład wpis:

jeśli (x \u003d\u003d 1)

if (y \u003d\u003d 1) puts ("x \u003d 1 i y \u003d 1");

else stawia ("x! \u003d 1");

podaje złe rozwiązanie, ponieważ w innym przypadku, niezależnie od stylu pisania, jest dopasowywane nie do pierwszego, ale do drugiego if. Dlatego poprawny zapis ostatniej linii powinien wyglądać tak:

else umieszcza ("x \u003d 1 i y! \u003d 1");

Jednak używając nawiasów klamrowych możesz również zaimplementować pierwszą konstrukcję:

jeśli (x \u003d \u003d 1)

if (y \u003d \u003d 1) puts ("x \u003d i y \u003d 1");

else stawia ("x! \u003d 1"); // poprawne rozwiązanie

Instrukcja Switch (patrz Rysunek 5.1, c) ma następujący format podstawowy:

przełącznik (switch_expression) case_operator;

Pozwala na przekazanie kontroli do jednej z kilku instrukcji oznaczonych wielkością liter na podstawie wartości switch_expression. Dowolna instrukcja w instrukcji case_ (w tym instrukcja pusta) może być oznaczona jedną (lub więcej) etykietami wariantów:

walizkaconstant_expression_i : case_operator_i;

gdzie każda stała_wyrażenie_i musi mieć unikatową wartość całkowitą (możliwą do zamiany na typ switch_expression) w otaczającej instrukcji switch.

Dozwolone jest posiadanie powtarzających się stałych wielkości liter w jednej instrukcji switch.

Wyciąg może mieć co najwyżej jedną domyślną etykietę:

domyślnie: default_operator;

Po oszacowaniu switch_expression wynik jest dopasowywany do jednego ze stałych_expression_i. Jeśli zostanie znalezione dopasowanie, kontrola jest przekazywana do case_operator_i z etykietą, dla której znaleziono dopasowanie. Jeśli nie zostanie znalezione żadne dopasowanie i istnieje domyślna etykieta, wówczas kontrola jest przekazywana do default_operator. Jeśli nie zostanie znalezione dopasowanie i nie ma domyślnej etykiety, żadne instrukcje nie są wykonywane. Aby zatrzymać wykonywanie grupy instrukcji dla określonego przypadku, użyj instrukcji break.

Programowanie strukturalne

Praktyka programowania wykazała potrzebę naukowo ugruntowanej metodologii opracowywania i dokumentowania algorytmów i programów. Metodologia ta powinna dotyczyć analizy pierwotnego problemu, dzieląc go na dość niezależne części i programując te części tak niezależnie od siebie, jak to tylko możliwe. Ta metodologia, która powstała we wczesnych latach 70-tych i ostatnio stała się powszechna, jest programowanie strukturalne.W swej istocie uosabia zasady podejścia systemowego w procesie tworzenia i działania. oprogramowanie KOMPUTER.

Na wszystkich etapach przygotowania do algorytmizacji problemu szeroko stosowana jest reprezentacja strukturalna algorytmu.

doprogramowanie strukturalne uosabia zasady systematycznego podejścia w procesie tworzenia i obsługi oprogramowania komputerowego. Strukturyzowane programowanie opiera się na następujących dość prostych zasadach:

    algorytm i program należy opracować etapami (krok po kroku).

    złożone zadanie należy podzielić na dość proste części, z których każda ma jedno wejście i jedno wyjście.

    logika algorytmu i programu powinna być oparta na jak najmniejszej liczbie dość prostych podstawowych struktur sterowania .

Programowanie strukturalne jest czasami nazywane programowaniem „no-GO TO”. Zaleca się unikanie używania operatora skoku, gdy tylko jest to możliwe, ale nie prowadzi to do powstania zbyt uciążliwych programów o określonej strukturze.

Przydatne przypadki użycia operatora skoku obejmują wyjście z pętli lub procedury przez specjalny warunek, że „z wyprzedzeniem” kończy pracę tego cyklu lub tej procedury, tj. kończenie pracy jakiejś jednostki strukturalnej (operator uogólniony), a tym samym tylko lokalnie naruszanie strukturyzacji programu.

Podstawą programowania strukturalnego jest twierdzenie strukturalne... To twierdzenie ustanawia, że \u200b\u200bbez względu na to, jak złożony jest problem, schemat odpowiedniego programu można zawsze przedstawić za pomocą ograniczonej liczby elementarnych struktur sterujących. Podstawowymi strukturami elementarnymi są struktury: śledzenie, rozgałęzianie i powtarzanie (pętla), każdy algorytm może być zaimplementowany jako kompozycja tych trzech struktur.

Pierwszy ( i) struktura - wpisz sekwencję (lub tylko sekwencję), drugą ( b) - struktura selekcji (rozgałęzienie), trzecia ( w) - struktura pętli z warunkiem wstępnym.

Gdy algorytm jest zapisywany werbalnie, struktury te mają odpowiednio następujące znaczenie:

"Wykonać ; wykonać
»,

jeśli następnie wykonaj , w przeciwnym razie wykonaj
»,

"aż do , wykonać »,

gdzie - stan: schorzenie; , ,
- działania.

W odniesieniu do języka Pascal, w którym idee programowania strukturalnego są najpełniej odzwierciedlone, w projektowaniu algorytmów wskazane jest użycie czterech bardziej elementarnych struktur: skróconej notacji dla rozgałęzień (ryc. ); konstrukcja wariantu (rys.16, ); struktura powtórzeń lub cykl z parametrem (rys. 16, ); struktura pętli z warunkiem końcowym (rys.6, ). Każda z tych struktur ma jedno wejście i jedno wyjście.

Rozgałęzienie (rozgałęzianie) to proces obliczeniowy, w którym jeden z możliwych obliczeń jest wybierany w zależności od weryfikacji określonych warunków.

W zależności od rodzaju i liczby sprawdzanych warunków rozróżnia się:

Rozgałęzienie z prostym warunkiem (warunek jest wyrażeniem relacji);

Rozgałęzienie z warunkiem złożonym (warunek jest wyrażeniem logicznym);

Złożone rozgałęzienie (kilka warunków).

Wywoływany jest wariant obliczeń ustalony w wyniku sprawdzenia warunku gałąź.

Cyklicznynazywany procesem wielokrotność powtórzenie części obliczeń przy zmianie co najmniej jednego ilości w nim zawartych.

Powtarza się sekcja obliczenia cykl... Operacje wykonywane w cyklu to pętla.

Nazywa się wielkość, która zmienia swoją wartość z cyklu na cykl parametr pętli.

Określa zależność łącząca bieżące i poprzednie wartości parametru pętli prawo zmienności parametru cyklu. Nazywa się zależność, nakazującą powtarzanie cyklu lub wyjście z niego warunek powtórzenia cyklu.

Wywoływane jest pełne przejście cyklu od początku do końca iteracja.

Wszystkie procesy cykliczne na podstawie określenia liczby powtórzeń (M) dzielimy na dwie klasy.

Arytmetykanazywany procesem cyklicznym, liczbę powtórzeń, w których można z góry określić, tj. nie zależy od wyników zliczania w treści pętli.

Wielokrotnyjest procesem cyklicznym, którego liczba powtórzeń zależy od wyników obliczeń w ciele pętli i nie może być z góry określona.

Niezależnie do jakiej klasy należy proces obliczeniowy, każda z nich zawiera wymagane elementy:

    wejście do cyklu (utworzenie wartości początkowej parametru cyklu);

    obliczenia w ciele cyklu (obliczanie bieżącej wartości funkcji, tworzenie nowej wartości parametru cyklu, a także operacje pomocnicze);

    wyjście z pętli (sprawdzenie warunku, który decyduje o powtórzeniu obliczeń lub ich zakończeniu).

W zależności od rodzaju ustawienia (zmiany) parametru cyklu, cykle arytmetyczne dzielimy na:

    cykle ze zmianą parametrów analitycznych;

    pętle z tabelą ustawienia parametru.

Wykonywanie pętli arytmetycznych, tj. wywoływane jest wielokrotne obliczanie wartości funkcji ze zmieniającymi się wartościami argumentu funkcja kart.

Rozpowszechniane dwie metody (strategie) tworzenia programuzwiązane z programowaniem strukturalnym:

- programowanie „od góry do dołu”;

- programowanie od dołu do góry.

Programowanie odgórne lub programowanie odgórne to technika programowania, w której programowanie rozpoczyna się od zdefiniowania celów rozwiązania problemu, po którym następuje sekwencyjne uszczegółowienie, kończąc na szczegółowym programie.

Takie podejście jest wygodne, ponieważ pozwala osobie na ciągłe myślenie na poziomie przedmiotu, bez zatrzymywania się na określonych operatorach i zmiennych. Ponadto możliwe staje się nierealizowanie niektórych podprogramów natychmiast, ale tymczasowe odłożenie do czasu zakończenia innych części.

Programowanie oddolne lub programowanie oddolne jest techniką tworzenia programów, która rozpoczyna się wraz z opracowaniem podprogramów (procedur, funkcji) w czasie, gdy tworzenie ogólnego schematu jeszcze się nie zakończyło.

Ta technika jest mniej preferowana niż programowanie odgórne, ponieważ często prowadzi do niepożądanych wyników, poprawek i wydłużenia czasu programowania.

Istnieją dwa rodzaje podprogramów - procedury i funkcje. Procedura po prostu wykonuje grupę instrukcji, a funkcja oblicza również pewną wartość i przekazuje ją z powrotem do programu głównego. Ta wartość jest określonego typu. Dane przekazywane są do podprogramu w postaci parametrów lub argumentów, które zwykle są opisane w nagłówku tak samo jak zmienne. Podprogramy są zwykle wywoływane po prostu przez wpisanie ich nazw z wymaganymi parametrami.

Podprogramy mogą być zagnieżdżane - podprogramy mogą być wywoływane nie tylko z programów głównych, ale także z dowolnych innych programów.

W niektórych językach programowania dozwolone jest wywołanie podprogramu z samego siebie. Ta technika nazywa się rekurencją i jest niebezpieczna, ponieważ może prowadzić do niekończącej się pętli - niekończącego się wywołania własnego.

Zalety programowania strukturalnego:

- zwiększa się niezawodność programów (dzięki dobrej strukturyzacji podczas projektowania program jest łatwy do testowania i nie stwarza problemów podczas debugowania);

- wzrasta efektywność programów (struktura programu ułatwia znajdowanie i korygowanie błędów, a poszczególne podprogramy mogą być zmieniane (modyfikowane) niezależnie od innych);

- zmniejsza się czas i koszty rozwój oprogramowania;

- poprawiono czytelność programów.

Wstępne programowanie zadania

Na komputerze można rozwiązywać zadania o różnym charakterze, na przykład: naukowe i inżynierskie; rozwój oprogramowania systemowego; uczenie się; zarządzanie procesami produkcyjnymi itp. W procesie przygotowywania i rozwiązywania problemów naukowo-inżynierskich na komputerze można wyróżnić następujące etapy:

1. przedstawienie problemu;

2. sformułowanie matematycznego modelu problemu;

3. wybór i uzasadnienie metody rozwiązania;

4. algorytmizacja procesu obliczeniowego;

5. programowanie;

6. debugowanie i testowanie programu;

7. rozwiązywanie problemu na komputerze i analiza wyników;

8. utrzymanie programu.

W zadaniach innej klasy może brakować niektórych etapów, np. W problemach z tworzeniem oprogramowania systemowego nie ma opisu matematycznego. Te etapy są ze sobą powiązane. Aby zmniejszyć liczbę takich zmian, na każdym etapie należy w miarę możliwości uwzględniać wymagania kolejnych etapów.

Sformułowanie problemu to etap werbalnego sformułowania, który określa cel rozwiązania, dane początkowe, podstawowe wzorce, warunki i ograniczenia stosowania tych wzorców. Analizowana jest natura i istota wszystkich wielkości użytych w zadaniu oraz określane są warunki, w jakich jest ono rozwiązywane.

Opis problemu musi spełniać następujące wymagania:

Jasne określenie celu, wskazujące rodzaj i charakterystykę ostatecznych wyników;

Reprezentacja wartości i wymiarów danych źródłowych;

Określenie wszystkich możliwych rozwiązań, warunki wyboru każdego;

Wyznaczenie granic stosowalności i działań w przypadku ich przekroczenia.

Stworzenie modelu matematycznego problemu - etap przekładania słownego sformułowania problemu na zbiór zależności matematycznych opisujących dane początkowe oraz obliczenie wyników pośrednich i końcowych.

Model matematyczny tworzony jest z pewną precyzją, założeniami i ograniczeniami. Ponadto w zależności od specyfiki rozwiązywanego problemu można skorzystać z różnych działów matematyki i innych dyscyplin.

Model matematyczny musi spełniać co najmniej dwa wymagania: realizm i wykonalność. Realizm rozumiany jest jako prawidłowe odzwierciedlenie modelu najważniejszych cech badanego zjawiska. Realizowalność jest osiągana przez rozsądną abstrakcję, oderwanie od drobnych szczegółów w celu zredukowania problemu do problemu ze znanym rozwiązaniem. Warunkiem wykonalności jest możliwość praktycznego wykonania niezbędnych obliczeń w wyznaczonym czasie przy dostępnych kosztach wymaganych zasobów.

Wynikowy model matematyczny musi spełniać następujące wymagania:

Najpierw sporządzany jest model danych początkowych, a następnie - obliczone zależności;

Oryginalny model danych nie zmienia wymiarów danych i nie wykorzystuje żadnych operacji matematycznych;

Oznaczenie wszystkich wielkości objętych zależnością nazwami określającymi ich istotę;

Wskazanie wymiarów wszystkich ilości używanych do kontroli i dalszej modernizacji rozwiązania;

Wybór i uzasadnienie metody rozwiązania to etap rozwoju lub selekcja z istniejącej metody rozwiązania, w tym wybór standardowych struktur procesów obliczeniowych (liniowych, rozgałęzionych, cyklicznych). O kryteriach wyboru decyduje model matematyczny rozwiązania (poprzedni etap), wymagania dotyczące wszechstronności metody i dokładności wyniku, ograniczenia sprzętu i oprogramowania. Uzasadniając wybór metody, należy wziąć pod uwagę różne czynniki i warunki, dokładność obliczeń, czas rozwiązania problemu na komputerze, wymaganą ilość pamięci i inne. W tym miejscu należy określić alternatywne metody i wybrane argumenty.

Algorytmizacja procesu obliczeniowego jest etapem opracowywania zestawu recept, które w unikalny sposób określają kolejność przekształcania danych początkowych w wyniki końcowe. Na tym etapie opracowywany jest algorytm rozwiązania problemu zgodnie z działaniami podanymi przez wybraną metodę rozwiązania. Proces przetwarzania danych jest podzielony na oddzielne, stosunkowo niezależne bloki i ustalana jest kolejność wykonywania bloków. Opracowywany jest schemat blokowy algorytmu.

Programowanie. Podczas kompilacji programu algorytm rozwiązania problemu jest tłumaczony na określony język programowania. Do programowania zwykle używa się języków wysokiego poziomu, dlatego skompilowany program wymaga jego przetłumaczenia na język maszynowy komputera. Po takim tłumaczeniu wykonywany jest odpowiedni program maszynowy.

1. Program musi być uniwersalny, to znaczy niezależny od określonego zbioru danych. Przykładowo, jeśli ilość przetwarzanych danych może ulec zmianie, należy zadbać o przechowywanie ich jak największej ilości. Program uniwersalny musi być w stanie obsłużyć błędy, które mogą pojawić się podczas przetwarzania informacji.

2. Zamiast stałych 1 lepiej jest używać zmiennych 2. Jeśli w programie używane są stałe, to po ich zmianie każda instrukcja 3 zawierająca poprzednią stałą musi zostać zmieniona w oryginalnym programie. Ta procedura jest czasochłonna i podatna na błędy. Program powinien zapewniać kontrolę nad wprowadzanymi danymi (w szczególności program nie powinien być wykonywany, jeśli dane są poza dopuszczalnym zakresem).

3. Kilka prostych technik może poprawić wydajność programu (to znaczy zmniejszyć liczbę wykonywanych operacji i skrócić czas programu). Te techniki obejmują:

Używanie mnożenia zamiast potęgowania;

Jeśli jakieś wyrażenie arytmetyczne występuje w obliczeniach kilka razy, to należy je wcześniej obliczyć i zapisać w pamięci komputera i użyć w razie potrzeby;

Organizując pętle, używaj zmiennych jako granic indeksów 4, a nie wyrażeń, które byłyby obliczane za każdym razem, gdy pętla jest przekazywana;

Zwróć szczególną uwagę na organizację pętli, usuwając z nich wszystkie obliczenia powtórzone z tymi samymi danymi i wykonując je przed wejściem do pętli.

4. Program powinien zawierać komentarze ułatwiające prześledzenie relacji logicznych i funkcji poszczególnych jego części.

Pisząc program, powinieneś ustrukturyzować jego tekst, aby był łatwy do odczytania. W szczególności program powinien wyraźnie widzieć, gdzie zaczyna się i kończy pętla.

Debugowanie programu to proces identyfikowania i korygowania błędów składniowych i logicznych w programie. Istota debugowania polega na tym, że wybierany jest pewien zbiór danych początkowych, nazywany zestawem testowym (testowym), a problem z tym zestawem jest rozwiązywany dwukrotnie: raz - wykonując program, drugi raz - w inny sposób, że tak powiem, na podstawie stanu problemu , "Ręcznie". Jeśli wyniki są zgodne, algorytm jest uważany za poprawny. Jako przypadek testowy możesz wybrać dowolne dane, które pozwolą Ci:

Zapewnij weryfikację wykonania wszystkich operacji algorytmu;

Zmniejsz liczbę obliczeń do minimum.

W toku kontroli syntaktycznej programu przez tłumacza ujawnia się konstrukcje i kombinacje symboli, które są niedopuszczalne z punktu widzenia przyjętych w danym języku reguł ich konstrukcji lub zapisu. Komputer wysyła komunikaty o błędach do programisty, a rodzaj i forma wydawania takich komunikatów zależą od typu języka i wersji używanego tłumacza.

Po wyeliminowaniu błędów składniowych logika programu jest sprawdzana w trakcie jego wykonywania z określonymi danymi początkowymi. W tym celu stosuje się metody specjalne, na przykład w programie wybierane są punkty kontrolne, dla których ręcznie obliczane są wyniki pośrednie. Wyniki te są porównywane z wartościami uzyskanymi przez komputer w tych punktach podczas wykonywania debugowanego programu. Dodatkowo w celu wyszukania błędów można wykorzystać debuggery, które na etapie debugowania wykonują specjalne akcje, na przykład usuwanie, zastępowanie lub wstawianie pojedynczych instrukcji lub całych fragmentów programu, wyświetlanie lub zmiana wartości określonych zmiennych.

Testowanie to testowanie, sprawdzanie poprawności programu jako całości lub jego części składowych.

Debugowanie i testowanie (test z języka angielskiego - testowanie) to dwa wyraźnie rozróżnialne i niepodobne etapy:

Podczas debugowania błędy składniowe i oczywiste błędy kodowania są lokalizowane i eliminowane;

W procesie testowania sprawdzana jest wydajność programu, który nie zawiera oczywistych błędów.

Testowanie wykrywa błędy, a debugowanie pozwala ustalić, dlaczego. W nowoczesnych systemach oprogramowania (Turbo Basic, Turbo Pascal, Turbo C itp.) Debugowanie często odbywa się za pomocą specjalnego narzędzia programowezwane debuggerami. Te narzędzia umożliwiają zbadanie wewnętrznego zachowania programu.

Program do debugowania zwykle zapewnia następujące funkcje:

Wykonywanie programu krok po kroku z zatrzymaniem po każdym poleceniu (operatorze);

Wyświetlanie bieżącej wartości dowolnej zmiennej lub znajdowanie wartości dowolnego wyrażenia, w tym przy użyciu funkcji standardowych; w razie potrzeby możesz ustawić nową wartość zmiennej;

Ustawienie w programie „punktów kontrolnych” tj. punkty, w których program czasowo wstrzymuje wykonywanie, aby można było ocenić wyniki pośrednie itp.

Podczas debugowania programów należy pamiętać o następujących kwestiach:

Na początku procesu debugowania powinieneś użyć prostych danych testowych;

Powstające trudności należy wyraźnie oddzielić i pojedynczo eliminować;

Bez względu na to, jak dokładnie program jest debugowany, decydującym etapem w określeniu jego przydatności do pracy jest kontrola programu na podstawie wyników jego wykonania na systemie testowym.

Aby wdrożyć metodę badawczą, wyniki referencyjne muszą być wcześniej podane lub znane. Konieczne jest obliczenie wyników odniesienia przed, a nie po uzyskaniu wyników maszyny. W przeciwnym razie istnieje niebezpieczeństwo niezamierzonego dostosowania obliczonych wartości do pożądanych uzyskanych wcześniej na maszynie.

Dane testowe powinny zapewniać sprawdzenie wszystkich możliwych błędów:

Każda gałąź algorytmu musi zostać przetestowana;

Następny przebieg testowy powinien kontrolować to, co nie zostało jeszcze przetestowane w poprzednich przebiegach;

Pierwszy test powinien być tak prosty, jak to tylko możliwe, aby sprawdzić, czy program w ogóle działa;

Operacje arytmetyczne w testach powinny być znacznie uproszczone, aby zmniejszyć ilość obliczeń;

Należy określić liczbę elementów sekwencji, dokładność obliczeń iteracyjnych, liczbę przebiegów pętli w przypadkach testowych w celu zmniejszenia ilości obliczeń;

Minimalizacja obliczeń nie powinna zmniejszać niezawodności sterowania;

Testowanie powinno być ukierunkowane i systematyczne, ponieważ losowy dobór danych wejściowych prowadziłby do trudności w ręcznym określaniu oczekiwanych wyników; ponadto, przy losowym wyborze danych testowych, wiele sytuacji może być niesprawdzonych;

Powikłanie danych testowych powinno następować stopniowo.

Proces testowania można podzielić na trzy etapy.

1. Sprawdzenie w normalnych warunkach. Zakłada testowanie w oparciu o dane charakterystyczne dla rzeczywistych warunków działania programu.

2. Sprawdzenie w ekstremalnych warunkach. Dane testowe obejmują wartości graniczne zakresu zmiennych wejściowych, które program powinien postrzegać jako prawidłowe. Typowe przykłady takich wartości to bardzo małe lub bardzo duże liczby i brak danych. Innym typem skrajnych warunków są marginesy danych, w których tablice składają się ze zbyt małej lub zbyt dużej liczby elementów.

3. Sprawdź w wyjątkowych sytuacjach. Odbywa się to na danych, których wartości leżą poza dopuszczalnym zakresem zmian. Wiadomo, że wszystkie programy są tworzone pod kątem przetwarzania ograniczonego zestawu danych. Dlatego ważne jest, aby uzyskać odpowiedź na następujące pytania:

Co się stanie, jeśli program, który nie jest przeznaczony do obsługi ujemnych i zerowych wartości zmiennych w wyniku błędu, będzie musiał radzić sobie właśnie z takimi danymi?

Jak zachowa się program pracujący z tablicami, jeśli liczba ich elementów przekroczy wartość określoną w deklaracji tablicy?

Co się stanie, jeśli liczby są za małe lub za duże?

Najgorsza sytuacja ma miejsce, gdy program interpretuje nieprawidłowe dane jako poprawne i daje niepoprawny, ale wiarygodny wynik.

Program musi sam odrzucić wszelkie dane, których nie jest w stanie poprawnie przetworzyć.

Rozwiązanie problemu na komputerze i analiza wyników. Po debugowaniu programu można go wykorzystać do rozwiązania zastosowanego problemu. W takim przypadku wielokrotne rozwiązanie problemu jest zwykle wykonywane na komputerze dla różnych zestawów danych początkowych. Uzyskane wyniki są interpretowane i analizowane przez specjalistę lub użytkownika, który wyznaczył zadanie.

Wsparcie programu:

Opracowany program do długotrwałego użytku jest z reguły instalowany na komputerze w postaci programu maszynowego gotowego do wykonania. Do programu dołączona jest dokumentacja, w tym instrukcja dla użytkownika. Ponieważ podczas instalowania programu na dysku w celu jego późniejszego użycia, oprócz plików z kodem wykonywalnym, instalowane są różne programy pomocnicze (narzędzia, podręczniki, dostosowania itp.), A także różne pliki niezbędne do obsługi programów z tekstem, grafiką, dźwiękiem i innymi Informacja.

Udoskonalenie programu rozwiązywania konkretnych problemów;

Opracowanie dokumentacji dla rozwiązanego problemu, modelu matematycznego, algorytmu, programu do ich wykorzystania.

1 Stała w programowaniu to sposób adresowania danych, których zmiana nie jest oczekiwana lub zabroniona przez dany program.

2 Zmienna w programowaniu imperatywnym to nazwany lub adresowany w inny sposób obszar pamięci, którego adres można wykorzystać do uzyskania dostępu do danych. Dane w zmiennej (czyli pod danym adresem pamięci) nazywane są wartością tej zmiennej.

W innych paradygmatach programowania, na przykład funkcjonalnym i logicznym, pojęcie zmiennej okazuje się nieco inne. W takich językach zmienną definiuje się jako nazwę, z którą można powiązać wartość, lub nawet jako miejsce przechowywania wartości.

3 Instrukcja lub instrukcja jest najmniejszą autonomiczną częścią języka programowania; Komenda. Program jest zwykle sekwencją instrukcji.

Wiele języków (na przykład C) rozróżnia stwierdzenie i definicję. Różnica polega na tym, że instrukcja wykonuje kod, a definicja tworzy identyfikator (to znaczy, że można myśleć o definicji jako instrukcji przypisania).

Poniżej przedstawiono podstawowe ogólne instrukcje dotyczące imperatywnych języków programowania.

4 Indeks w językach programowania to element wyliczonego zbioru wskazujący na określony element tablicy, zwykle nieujemną skalarną liczbę całkowitą.

Istnieją trzy sposoby indeksowania elementów tablicy za pomocą nieujemnych liczb całkowitych:

pierwszy element tablicy ma indeks 0;

pierwszy element tablicy ma indeks 1;

n ("indeks zaczynający się od n")

indeks bazowy tablicy można dowolnie wybrać. Zazwyczaj języki programowaniazezwolenie na „indeks zaczynający się od n” umożliwia również wybieranie wartości ujemnych jako indeksów tablic, a także innych skalarnych typów danych, takich jak wyliczenia lub symbole.

Tablica może mieć wiele wymiarów, dlatego powszechną praktyką jest uzyskiwanie dostępu do tablicy przy użyciu wielu indeksów. Na przykład dwuwymiarowa tablica z trzema wierszami i czterema kolumnami może być adresowana do elementu w drugim wierszu i czwartej kolumnie przy użyciu wyrażenia: (w języku, w którym wiersz ma pierwszeństwo) i (w języku, w którym kolumna ma pierwszeństwo) w przypadek z indeksem zaczynającym się od zera. W ten sposób używane są dwa indeksy tablice dwuwymiarowe, trzy dla tablicy trójwymiarowej i n dla tablicy n-wymiarowej.

Języki i technologie programowania

Pierwsze programy polegały na ustawianiu przełączników kluczykowych z przodu urządzenia komputerowego. Oczywiście w ten sposób można skompilować tylko małe programy. Wraz z rozwojem technologii komputerowej pojawił się język maszynowy, za pomocą którego programista mógł ustawiać instrukcje, operując komórkami pamięci, w pełni wykorzystując możliwości maszyny. Jednak korzystanie z większości komputerów na poziomie języka maszynowego jest trudne, szczególnie w przypadku operacji we / wy. Dlatego musieliśmy zrezygnować z jego używania. Na przykład, aby odczytać blok danych z dyskietki, programista może użyć 16 różnych poleceń, z których każde wymaga 13 parametrów, takich jak numer bloku na dysku, numer sektora na ścieżce itp. Po zakończeniu operacji na dysku sterownik zwraca 23 wartości odzwierciedlające obecność i typy błędów do analizy. W języku maszynowym nazywane są „słowa” instrukcje, z których każda reprezentuje jedną podstawową akcję dla jednostka centralna, jak na przykład odczyt informacji z komórki pamięci. Każdy model procesora ma własny zestaw instrukcji maszynowych, chociaż większość z nich jest taka sama. Jeśli procesor A w pełni rozumie język procesora B, to mówi się, że procesor A jest kompatybilny z procesorem B. Procesor B zostanie nazwany niezgodnym z procesorem A, jeśli A ma instrukcje, które nie są rozpoznawane przez procesor B. W przypadku, gdy konieczne jest posiadanie wydajnego programu zamiast maszyny języki są używane blisko nich języki zorientowane maszynowo - asemblery. Ludzie używają instrukcji mnemonicznych zamiast instrukcji maszynowych.

Ale nawet praca z asemblerem jest dość skomplikowana i wymaga specjalnego przeszkolenia. Na przykład dla procesora Zilog Z80 instrukcja maszynowa 00000101 nakazuje procesorowi zmniejszenie rejestru B. W języku asemblera będzie to również zapisane jako DEC B.

Programowanie strukturalne

Kolejny krok został podjęty w 1954 roku, kiedy powstał pierwszy język wysokiego poziomu - Fortran (ang. FORTRAN - FORmula TRANslator). Języki wysokiego poziomu naśladują języki naturalne, używając niektórych słów języka mówionego i popularnych symboli matematycznych. Te języki są wygodniejsze dla ludzi, z ich pomocą można pisać programy o długości do kilku tysięcy linii. Jednak łatwo zrozumiały w krótkich programach język ten stał się nieczytelny i trudny do opanowania w przypadku dużych programów. Rozwiązanie tego problemu pojawiło się po wynalezieniu strukturalnych języków programowania (ang. ustrukturyzowany język programowania), takie jak Algol (1958), Pascal (1970), C (1972).

Programowanie strukturalne obejmuje dobrze zdefiniowane struktury sterujące, bloki programowe, instrukcje bez skoku (GOTO), samodzielne procedury, rekursję i obsługę zmiennych lokalnych. Istota tego podejścia polega na możliwości podzielenia programu na jego elementy składowe. Stworzony również funkcjonalny języki (stosowane) (przykład: Lisp - eng. Przetwarzanie LISt, 1958) i łamigłówka języki (przykład: Prolog - eng. Programowanie w LOGic, 1972). Chociaż programowanie strukturalne dawało znakomite wyniki, gdy było używane, nawet zawodziło, gdy program osiągnął określoną długość. Pisanie bardziej złożonego (i dłuższego) programu wymagało nowego podejścia do programowania.

Ostatecznie, w późnych latach siedemdziesiątych i wczesnych osiemdziesiątych XX wieku, opracowano zasady programowania obiektowego. OOP łączy najlepsze zasady programowania strukturalnego z potężnymi nowymi koncepcjami, których rdzeń to kapsułkowanie, polimorfizm i dziedzictwo. Przykłady języków zorientowanych obiektowo to: Object Pascal, C ++, Java itp. OOP pozwala optymalnie organizować programy poprzez rozbicie problemu na jego części składowe i pracę z każdym z nich oddzielnie. Program w języku zorientowanym obiektowo, rozwiązujący jakiś problem, tak naprawdę opisuje część świata związaną z tym problemem.

Programowanie strukturalne stanowi dotychczas największy postęp w tej dziedzinie. Pomimo tego, że prawie każdy ma ogólna koncepcja o nim prawie nikt nie może podać konkretnej i jasnej definicji tego terminu. Programowanie strukturalne stawia sobie za główny cel pisanie programów o najmniejszej złożoności, zmuszając programistę do jasnego myślenia, dzięki czemu program jest łatwiejszy do zrozumienia. Jego tekst musi być tak skonstruowany, aby był czytelny od góry do dołu. Warunek ten jest naruszany, jeśli w kodzie programu zostaną napotkane instrukcje przejdź do, ponieważ naruszają one strukturę całego segmentu programu. Pomimo tego, że tego wskaźnika nie można uznać za najwygodniejszy, nadal można powiedzieć, że obecność w kodzie programu ten operator jest najbardziej rzucającym się w oczy rodzajem zaburzenia strukturalnego. Korpusy modułów i wykorzystywane struktury muszą być odporne na awarie sprzętu, błędy w programach i zniekształcenia oryginalnych danych.

Podstawowe zasady programowania strukturalnego są następujące. Każdy program można łatwo zsyntetyzować w oparciu o podstawowe konstrukcje trzech głównych typów:

Prosta konsystencja;

Warunki lub alternatywy;

Powtórzenia, czyli pętle i iteracje.

Jednocześnie można używać jednego lub dwóch dowolnego rodzaju. Każda konstrukcja ma jedną cechę - pojedynczy punkt przeniesienia kontroli na strukturę i pojedynczy punkt wejścia do struktury. Taka konstrukcja ma znaczenie dyscyplinujące i systematyzujące.

Prostota początkowych konstrukcji w programowaniu strukturalnym zapobiega połączeniom informacyjnym, a także mylącym transferom sterowania. Złożoność programów jest zauważalnie zmniejszona wraz ze wzrostem struktury modułów, zwiększa się ich przejrzystość, a to pomaga zmniejszyć liczbę błędów. Strukturyzacja ma jednak również wadę - za piękno i przejrzystość kodu programu trzeba zapłacić dodatkową pamięcią, a także czasem potrzebnym na ich implementację na komputerze.

Programowanie strukturalne, czyli struktura samych tekstów programu, zależy całkowicie od tego, jaki język jest do tego używany. Oczywiście pojawia się pytanie, który z nich najlepiej pasuje. Nowoczesne narzędzia programistyczne są uważane za najlepsze języki do wdrażania ustrukturyzowanego podejścia do programowania. Do najpopularniejszych należą Basic, Pascal i FoxBASE. Na przykład praktycznie niemożliwe jest wdrożenie zasad określonych w koncepcji programowania strukturalnego. Ten język koncentruje się na pisaniu kodu programowania niskiego poziomu.

Programowanie strukturalne zasadniczo koncentruje się na komunikacji z ludźmi, a nie maszynami, dlatego ułatwia pisanie programów, które stanowią jasne i proste rozwiązanie danego problemu. Programista musi myśleć w kategoriach podstawowych konstrukcji strukturalnych.

Jeśli mówimy o położeniu względem wspomnianego wcześniej idź do operatora, to należy go unikać wszędzie tam, gdzie jest to możliwe, ale nie powinno to w żaden sposób wpływać na czytelność programu. Czasami użycie tego operatora okazuje się po prostu konieczne do wyjścia z określonego segmentu programu lub cyklu, a także w celu uniknięcia pojawienia się zbyt głębokich wideł, zwłaszcza że przejście wiąże się z niższymi poziomami programów. W takim przypadku struktura programu pozostaje czytelna od góry do dołu. Najgorsze z danego operatora wiąże się z przejściem od dołu do góry.

Aby ułatwić czytanie, programy często dodają puste wiersze między sekcjami. Warto napisać tekst programu z przesunięciami, abyś mógł odczytać kolejność działań i liczbę załączników.

Paradygmaty programowania

Programowanie strukturalne - metodyka tworzenia oprogramowania, która polega na prezentacji programu w postaci hierarchicznej struktury blokowej. Zaproponowany w latach 70. przez E. Dijkstroy i wsp.

Zgodnie z tą metodologią każdy program jest budowany bez użycia operatora goto z trzech podstawowych struktur sterowania: sekwencja, gałąź, pętla; ponadto stosowane są podprogramy. W tym przypadku tworzenie programu odbywa się krok po kroku, metodą „z góry na dół”.

Ustrukturyzowana metodologia programowania pojawiła się jako konsekwencja coraz większej złożoności zadań rozwiązywanych na komputerach, a co za tym idzie - komplikacji oprogramowania. W latach siedemdziesiątych liczba i złożoność programów osiągnęła taki poziom, że tradycyjny (nieustrukturyzowany) rozwój programów przestał spełniać potrzeby praktyki. Programy stały się zbyt skomplikowane, aby można je było właściwie utrzymywać. Dlatego konieczne było usystematyzowanie procesu rozwoju i struktury programu.

Strukturyzowana metodologia tworzenia oprogramowania została uznana za „najsilniejszą formalizację lat 70-tych”.

Według Bertranda Meyera „Rewolucja w programowaniu, której pionierem był Dijkstroy, doprowadziła do ruchu znanego jako programowanie strukturalne, które zaproponowało systematyczne, racjonalne podejście do projektowania programów. Programowanie strukturalne stało się podstawą wszystkiego, co zostało zrobione w metodologii programowania, w tym programowania obiektowego ”.

Encyklopedyczny YouTube

    1 / 5

    ✪ Programowanie strukturalne. Podstawowe zasady

    ✪ Pascal od podstaw [h1]. Pierwszy program.

    ✪ Lekcja 7. Operatory wyjścia zapisu / zapisu. Prosty program... Programowanie Pascal / Pascal

    ✪ Podstawy programowania - # 5 - Arytmetyka i wyrażenia logiczne

    ✪ 003. Logiczne algorytmy klasyfikacji - K.V. Woroncowa

    Napisy na filmie obcojęzycznym

Historia

Początkowo idea programowania strukturalnego zrodziła się w związku z operatorem goto i wątpliwościami co do celowości jego użycia. Heinz Zemanek po raz pierwszy wyraził takie wątpliwości na spotkaniu na temat języka Algol na początku 1959 roku w Kopenhadze. Jednak ten spektakl nie przyciągnął uwagi i nie miał żadnych konsekwencji. Edsger Dijkstra wspomina: „Do pewnego stopnia winię siebie za to, że nie byłem w stanie docenić znaczenia tego pomysłu w tamtym czasie”.

Sytuacja zmieniła się dramatycznie dziesięć lat później, kiedy Dijkstra opublikował w marcu 1968 roku swój słynny list „Przejdź do oświadczenia uważanego za szkodliwy”. To prawdziwie historyczny dokument, który miał zauważalny wpływ na dalszy rozwój programowania.

Los samego dokumentu jest bardzo ciekawy. Faktem jest, że Dijkstra nadał artykułowi zupełnie inny tytuł: „Argumenty przeciwko stwierdzeniu GO TO” (Sprawa przeciwko oświadczeniu GO TO).

Jednak w momencie publikacji wydarzyło się coś niezrozumiałego - z jakiegoś powodu artykuł w tajemniczy sposób zamienił się w „List do Redakcji”, a poprzedni tytuł równie tajemniczo zniknął. Co naprawdę się wydarzyło? Dijkstra wyjaśnił tajemnicze przekształcenie artykułu w list dopiero wiele lat później, w 2001 roku, rok przed śmiercią.

cel, powód

Celem programowania strukturalnego jest zwiększenie produktywności programistów, w tym przy tworzeniu dużych i złożonych systemów oprogramowania, zmniejszenie liczby błędów oraz uproszczenie debugowania, modyfikacji i konserwacji oprogramowania.

Cel ten został wyznaczony ze względu na rosnącą złożoność programów i niezdolność programistów i menedżerów dużych projektów oprogramowania do radzenia sobie z problemami, które pojawiły się w latach 60. i 70. XX wieku w związku z rozwojem narzędzi programistycznych.

Kod spaghetti

Programowanie strukturalne ma na celu w szczególności wyeliminowanie bałaganu i błędów w programach spowodowanych trudnościami w czytaniu kodu, niesystematyzowany kod źródłowy programu, który jest niewygodny w percepcji i analizie. Taki tekst jest często określany jako „kod spaghetti”.

Kod spaghetti można debugować i działać poprawnie z wysoka wydajność, ale jest niezwykle trudny do utrzymania i rozwoju. Udoskonalanie kodu spaghetti w celu dodania nowych funkcji czasami niesie ze sobą znaczny potencjał dla nowych błędów. Z tego powodu refaktoryzacja kodu, główne lekarstwo na spaghetti, staje się prawie nieunikniona.

Goto oświadczenie

Od lat 70. operator goto znajduje się w centrum systematycznej i narastającej krytyki. Nieprawidłowe i bezmyślne użycie instrukcji goto w kodzie źródłowym programu powoduje powstanie zagmatwanego, nieczytelnego „kodu spaghetti”. Zrozumienie kolejności wykonania i współzależności fragmentów z tekstu takiego kodu jest prawie niemożliwe.

Ten punkt widzenia został po raz pierwszy odzwierciedlony w artykule Edsgera Dijkstry „Operator Go To jest uważany za szkodliwy”. Dijkstra zauważył, że jakość kodu programu jest odwrotnie proporcjonalna do liczby zawartych w nim instrukcji goto. Artykuł stał się szeroko znany, w wyniku czego poglądy na temat wykorzystania operatora goto zostały znacząco zmienione. W Uwagach na temat programowania strukturalnego Dijkstra uzasadnił fakt, że dla kodu bez goto znacznie łatwiej jest sprawdzić poprawność formalną.

Kod z goto jest trudny do sformatowania, ponieważ może naruszać hierarchię wykonywania (paradygmat programowania strukturalnego), w związku z czym wcięcia, zaprojektowane tak, aby odzwierciedlały strukturę programu, nie zawsze mogą być ustawione poprawnie. Ponadto instrukcja goto zakłóca optymalizację struktur sterowania przez kompilatory.

Niektóre zastosowania goto mogą powodować problemy z logiką wykonywania programu:

  • Jeśli zmienna zostanie zainicjalizowana (pobiera wartość) w jednym miejscu, a następnie jest używana dalej, to przeskok do punktu po inicjalizacji, ale przed użyciem, doprowadzi do tego, że wartość, która była w pamięci przydzielona zmiennej przed momentem alokacji (i co jest zwykle arbitralne i przypadkowe).
  • Przekazywanie kontroli wewnątrz treści pętli powoduje pominięcie kodu inicjalizacji pętli lub sprawdzenie warunku początkowego.
  • Podobnie przeniesienie sterowania do procedury lub funkcji prowadzi do pominięcia jego początkowej części, w której wykonywana jest inicjalizacja (alokacja pamięci dla zmiennych lokalnych).

Argumenty przeciwko instrukcji goto okazały się tak silne, że uznano je za wysoce niepożądane w programowaniu strukturalnym. Znajduje to odzwierciedlenie w projektowaniu nowych języków programowania. Na przykład goto jest zabronione w Javie i Rubim. W wielu współczesnych językach jest on nadal porzucany ze względu na skuteczność w tych rzadkich przypadkach, gdy użycie goto jest uzasadnione. W ten sposób goto przetrwał w Adzie, jednym z najbardziej przemyślanych architektonicznie języków w historii.

Jednak w językach wysokiego poziomu, w których zachowano ten operator, zwykle nakłada się surowe ograniczenia na jego użycie, uniemożliwiając stosowanie najniebezpieczniejszych metod jego użycia: na przykład zabrania się przenoszenia sterowania z zewnątrz pętli, procedury lub funkcji wewnątrz. Standard języka C ++ zabrania przechodzenia goto podczas inicjalizacji zmiennej.

Twierdzenie o programowaniu strukturalnym

Twierdzenie zostało sformułowane i udowodnione przez włoskich matematyków Corrado Böhm i Giuseppe Jacopini. Wydali go w 1965 r. Po włosku, aw 1966 r. Po angielsku. Wraz z twierdzeniem, w artykule Boehma i Yakopiniego opisano metody konwersji algorytmów niestrukturalnych na algorytmy strukturalne na przykładzie języka programowania P ′ ′ stworzonego przez Boehma. Język P ′ ′ jest pierwszym kompletnym językiem programowania Turinga bez instrukcji goto.

Twierdzenie Boehma-Jacopiniego jest napisane skomplikowanym językiem i nietypową notacją. Jeśli użyjemy nowoczesnej terminologii i notacji, przyjmie ona postać:

Każdy program podany w formie schematu blokowego można przedstawić za pomocą trzech struktur sterujących:

  • sekwencja - wskazany przez:f WTEDY g,
  • rozgałęzienie - wskazany przez:JEŚLI p TO f INNY g,
  • cykl - wskazany przez:GDY p DO f,

gdzie f, g - schematy blokowe z jednym wejściem i jednym wyjściem,

P - warunek, TO, JEŚLI, INNE, GDY, DO - słowa kluczowe.

Wyjaśnienie. Formuła f TO g oznacza co następuje: najpierw wykonywany jest program f, a następnie wykonywany jest program g.

Boehm i Jacopini nie używali terminu programowanie strukturalne. Niemniej jednak twierdzenie przez nich udowodnione (i jego późniejsze odmiany przez różnych autorów) zostało później nazwane „Twierdzeniem o programowaniu strukturalnym”, „Twierdzeniem o strukturze”, „Twierdzeniem o strukturalizacji”.

Zasady programowania strukturalnego

Tworzenie i rozwój programowania strukturalnego jest związane z nazwiskiem Edsger Dijkstra.

Zasada 1. Należy unikać używania operatora goto.

Zasada 2. Każdy program jest zbudowany z trzech podstawowych struktur kontrolnych: sekwencji, gałęzi, pętli.

Zasada 3. W programie podstawowe struktury sterowania mogą być zagnieżdżane w sobie w dowolny sposób. Żadna inna kontrola przepływu nie jest dostępna.

Zasada 4. Powtarzające się fragmenty programu można sformatować jako podprogramy (procedury i funkcje). W ten sam sposób (w postaci podprogramów) można zaprojektować logicznie integralne fragmenty programu, nawet jeśli nie są one powtarzane.

Zasada 5. Każda logicznie kompletna grupa instrukcji powinna być sformatowana jako blok. Bloki są podstawą programowania strukturalnego.

Blok to logicznie pogrupowany fragment kodu źródłowego, na przykład zestaw instrukcji zapisanych w wierszu w kod źródłowy programy. Pojęcie blok oznacza, że \u200b\u200bblok instrukcji należy traktować jako pojedynczą instrukcję. Bloki służą do ograniczenia zakresu zmiennych i funkcji. Bloki mogą być puste lub zagnieżdżone jeden w drugim. Granice bloków są ściśle określone. Na przykład w instrukcji if blok jest ograniczony kodem BEGIN..END (w Pascalu) lub nawiasy klamrowe (...) (w C) lub wcięcie (w Pythonie).

Zasada 6. Wszystkie powyższe konstrukcje muszą mieć jedno wejście i jedno wyjście.

Dowolne konstrukcje sterujące (na przykład w naczyniu do spaghetti) mogą mieć dowolną liczbę wejść i wyjść. Ograniczając się do sterowania strukturami z jednym wejściem i jednym wyjściem, jesteśmy w stanie zbudować dowolne algorytmy o dowolnej złożoności przy użyciu prostych i niezawodnych mechanizmów.

Zasada 7. Rozwój programu odbywa się krok po kroku, metodą „odgórną” (metoda z góry na dół) .

Metoda odgórna

Najpierw napisany jest tekst programu głównego, w którym zamiast każdego spójnego logicznego fragmentu tekstu wstawiane jest wywołanie podprogramu, który wykona ten fragment. Zamiast rzeczywistych, działających podprogramów do programu wstawiane są pozorne części - bublektóre, mówiąc prosto, nic nie robią.

Dokładniej, odgałęzienie spełnia wymagania interfejsu wymienianego fragmentu (modułu), ale nie spełnia swoich funkcji lub spełnia je tylko częściowo. Następnie odgałęzienia są zastępowane lub modyfikowane w rzeczywiste w pełni funkcjonalne fragmenty (moduły) zgodnie z planem programowania. Na każdym etapie realizacji już utworzony program musi działać poprawnie w stosunku do niższego poziomu. Wynikowy program jest sprawdzany i debugowany.

Należy również zauważyć, że w przedmowie do programowania strukturalnego Tony Hoare zauważa, że \u200b\u200bzasady programowania strukturalnego mogą być stosowane w równym stopniu do programowania odgórnego i oddolnego.

Podprogram

Podprogram jest podstawowym elementem programowania strukturalnego. Początkowo podprogramy pojawiły się jako sposób na optymalizację programów pod względem ilości zajmowanej pamięci - pozwalały nie powtarzać identycznych bloków kodu w programie, tylko je raz opisać i wywołać w razie potrzeby. Do tej pory ta funkcja podprogramów stała się pomocnicza, ich głównym celem jest taka struktura programu, aby był łatwiejszy do zrozumienia i utrzymania.

Przydzielenie zestawu działań do podprogramu i wywołanie go w razie potrzeby pozwala logicznie wybrać integralne podzadanie, które ma typowe rozwiązanie... Ta akcja ma jeszcze jedną (poza oszczędzaniem pamięci) przewagę nad powtarzaniem akcji tego samego typu. Każda zmiana (naprawa błędu, optymalizacja, rozszerzenie funkcjonalności) dokonana w podprogramie jest automatycznie odzwierciedlana we wszystkich jego wywołaniach, natomiast w przypadku duplikacji każda zmiana musi być dokonana w każdym wystąpieniu zmodyfikowanego kodu.

Nawet w tych przypadkach, gdy pojedynczy wykonywany zestaw działań jest przypisany do podprogramu, jest to uzasadnione, ponieważ pozwala zmniejszyć rozmiar całkowych bloków kodu, które składają się na program, to znaczy uczynić program bardziej zrozumiałym i obserwowalnym.

Korzyści z programowania strukturalnego

Przestrzeganie zasad programowania strukturalnego sprawiło, że teksty programów, nawet dość duże, były normalnie czytelne. Zrozumienie programów stało się znacznie łatwiejsze, stało się możliwe tworzenie programów w normalnym trybie przemysłowym, kiedy program jest łatwo zrozumiały nie tylko dla jego autora, ale także dla innych programistów. Dzięki temu wysiłkiem zespołów programistycznych można było rozwijać wystarczająco duże jak na owe czasy systemy oprogramowania i towarzyszyć tym kompleksom przez wiele lat, nawet w obliczu nieuchronnych zmian kadrowych.

  1. Programowanie strukturalne pozwala znacznie zmniejszyć liczbę opcji budowania programu według tej samej specyfikacji, co znacznie ogranicza złożoność programu i, co ważniejsze, ułatwia jego zrozumienie innym programistom.
  2. W programach strukturalnych operatory logicznie połączone są wizualnie bliżej, a słabo połączone są dalej, co pozwala obejść się bez schematów blokowych i innych graficznych form wyświetlania algorytmów (w rzeczywistości sam program jest własnym schematem blokowym).
  3. Proces testowania i debugowania programów strukturalnych jest znacznie uproszczony.

Przejrzystość i czytelność programów

Strukturyzowane programowanie znacznie poprawia przejrzystość i czytelność programów. Edward Yourdon wyjaśnia:

Zachowanie wielu programów niestrukturalnych jest często bliższe ruchom Browna niż jakiemukolwiek zorganizowanemu procesowi. Każda próba przeczytania listy prowadzi do rozpaczy, że w takim programie zwykle wykonywanych jest kilka instrukcji, po czym kontrola jest przenoszona do punktu kilka stron poniżej. Tam wykonywanych jest kilka dodatkowych operatorów, a sterowanie jest ponownie przenoszone do jakiegoś losowego punktu. Tutaj wykonuje się więcej operatorów itp. Po kilku takich programach czytelnik zapomina, jak to się wszystko zaczęło. I gubi tok myśli.

Z kolei programy strukturalne są zwykle konsekwentnie organizowane i wykonywane.

Poprawę czytelności programów ustrukturyzowanych tłumaczy fakt, że brak instrukcji goto umożliwia odczyt programu z góry na dół bez przerw spowodowanych przenoszeniem sterowania. Dzięki temu od razu (na pierwszy rzut oka) można odkryć warunki niezbędne do zmodyfikowania określonego fragmentu programu.

Dwuwymiarowe programowanie strukturalne

R-technologia produkcji programów, czyli „technologia programowania dwuwymiarowego” powstała w. System graficzny technologii programowania R jest ustalony w normach GOST 19.005-85, GOST R ISO / IEC 8631-94 i międzynarodowej normie ISO 8631H.

Autor technologii programowania R, doktor nauk fizycznych i matematycznych, profesor Igor Velbitsky zaproponował zrewidowanie samej koncepcji „struktury programu”. Jego zdaniem „struktura to pojęcie wielowymiarowe. Dlatego odwzorowanie tej koncepcji przy użyciu tekstów liniowych (sekwencji operatorów) praktycznie neguje zalety podejścia strukturalnego. Ogromne zdolności asocjacyjne aparatu wzrokowego i aparatu ludzkiego myślenia są wykorzystywane praktycznie na próżno - do rozpoznawania obrazów strukturalnych w postaci jednolitego ciągu symboli. ”

Metodologia dwuwymiarowego programowania strukturalnego znacznie różni się od klasycznego jednowymiarowego (tekstowego) programowania strukturalnego.

Idee programowania strukturalnego powstały, gdy grafika komputerowa jeszcze nie istniała, a głównym narzędziem algorytmisty i programisty był tekst jednowymiarowy (liniowy lub schodkowy). Przed nadejściem grafiki komputerowej stosowano metodologię klasycznego programowania strukturalnego najlepszy decyzja.

Wraz z pojawieniem się grafiki komputerowej sytuacja się zmieniła. Za pomocą wyrazistych środków graficznych stało się możliwe modyfikowanie, rozwijanie i uzupełnianie trzech typów podstawowych (tekstowych) struktur sterujących, a także całkowite porzucenie słów kluczowych, a potem, inaczej, case, switch, break, while, do, repeat, aż, za, foreach, continue, loop, exit, when, last itp. i zastąp je grafiką kontrolną, czyli użyj dwuwymiarowego programowania strukturalnego.

Ważnym problemem jest złożoność współczesnego programowania i poszukiwanie sposobów jej przezwyciężenia. Według kandydata nauki techniczne, Docent Evgeny Pyshkin, badanie programowania strukturalnego wyłącznie jako narzędzia do opracowywania tekstów programowych w oparciu o główną „triadę strukturalną” (sekwencja liniowa, rozgałęzienie i pętla) jest niewystarczające i w rzeczywistości neguje analizę zalet podejścia strukturalnego. W procesie pokonywania zasadniczej złożoności oprogramowania najważniejszym narzędziem jest wizualizacja projektowania i programowania.

Zobacz też

Uwagi

  1. Meyer B. Poczuj klasę. Naucz się dobrze programować z obiektami i kontraktami. - Per. z angielskiego. - M.: National Open University INTUIT: BINOM. Laboratorium wiedzy, 2011. - 775p. - S. 208. - ISBN 978-5-9963-0573-5
  2. E. Dijkstra. Instrukcja goto jest uważana za szkodliwą
  3. Dijkstra E. Przejdź do oświadczenia uważanego za szkodliwe // Komunikaty ACM, tom 11, nr. 3, marzec 1968, ss. 147-148. - Association for Computing Machinery, Inc.
  4. Zobacz także materiały z archiwów Dijkstry. Archiwum E. W. Dijkstry. Rękopisy Edsgera W. Dijkstry. - Wydział Informatyki Uniwersytetu Teksańskiego w Austin
  5. Rękopis EWD1308 z archiwów Dijkstry.
  6. Transkrypcja EWD1308 z archiwów Dijkstry. Co doprowadziło do „Notatek o programowaniu strukturalnym” - Nuenen, 10 czerwca 2001 r. - Wydział Informatyki. Uniwersytet Teksasu w Austin, USA
  7. Linger R., Mills H., Witt B. Teoria i praktyka programowania strukturalnego. - Per. z angielskiego. - M .: Mir, 1982. - 406s. - S. 7.
  8. John Vlissides, Kyle Brown, Gerard Meszaros AntiPatterns: The Survival Guide. ...

DZWON

Są tacy, którzy czytają tę wiadomość przed tobą.
Zapisz się, aby otrzymywać najnowsze artykuły.
E-mail
Imię
Nazwisko
Jak chcesz przeczytać The Bell
Bez spamu