Jaka jest różnica między programowaniem imperatywnym, proceduralnym a programowaniem strukturalnym?

85

Badając (książki, Wikipedię, podobne pytania dotyczące SE itp.) Zrozumiałem, że programowanie imperatywne jest jednym z głównych paradygmatów programistycznych, w którym opisuje się szereg poleceń (lub instrukcji) do wykonania przez komputer (więc jesteś ładna wiele nakazuje podejmować określone działania, stąd nazwa „imperatyw”). Na razie w porządku.

Z drugiej strony programowanie proceduralne jest szczególnym typem (lub podzbiorem) programowania imperatywnego, w którym używa się procedur (tj. Funkcji) do opisania poleceń, które komputer powinien wykonać.

Pierwsze pytanie : czy istnieje imperatywny język programowania, który nie jest proceduralny? Innymi słowy, czy możesz mieć programowanie imperatywne bez procedur?

Aktualizacja : Wydaje się, że odpowiedź na to pierwsze pytanie. Język MOŻE być konieczny, nie będąc proceduralnym ani uporządkowanym. Przykładem jest czysty język asemblera.

Następnie masz również programowanie strukturalne, które wydaje się być innym typem (lub podzbiorem) programowania imperatywnego, które pojawiło się, aby usunąć poleganie na instrukcji GOTO.

Drugie pytanie : Jaka jest różnica między programowaniem proceduralnym a programowaniem strukturalnym? Czy możesz mieć jeden bez drugiego i odwrotnie? Czy możemy powiedzieć, że programowanie proceduralne jest podzbiorem programowania strukturalnego, jak na obrazie?

wprowadź opis zdjęcia tutaj

Daniel Scocco
źródło

Odpowiedzi:

52

Wiele terminów można ponownie wykorzystać (często niewłaściwie) na temat języków programowania, zwłaszcza tych innych niż zorientowane obiektowo.

Oto kilka małych opisów warunków.

  1. Programowanie imperatywne - W dawnych dobrych czasach, gdy programowanie było w dużej mierze w asemblerze, kod zawierałby mnóstwo GOTO. Nawet języki wyższego poziomu, takie jak FORTRAN i BASIC, zaczęły używać tych samych prymitywów. W tym paradygmacie programowania cały program jest pojedynczym algorytmem lub pełną funkcjonalnością zapisaną liniowo - krok po kroku. To jest imperatywny styl . Zrozum, że nawet w nowoczesnym języku C można naprawdę napisać całkowicie kiepską pracę imperatywną, ale kodowanie w językach wyższego poziomu jest dość łatwe.

  2. Programowanie strukturalne i modułowe - Najczęściej powinniśmy móc używać tego terminu zamiennie, ale z niewielkimi różnicami. Kiedy języki wyższego poziomu zaczęły się bogacić, zdano sobie sprawę, że wszystkie jednostki pracy powinny zostać podzielone na mniejsze, możliwe do przeszukiwania części - to znaczy, kiedy powstały funkcje, a programowanie stało się hierarchią funkcji i wiele z niższych poziomów można było ponownie wykorzystać.

    • Programowanie strukturalne to dowolne programowanie, gdy funkcjonalność jest podzielona na jednostki takie jak for loop, while loop, if... thenstruktura bloków itp.
    • Również tutaj można ponownie użyć fragmentu kodu (funkcji).
    • W programowaniu modułowym można stworzyć fizyczną formę pakietu - tj. Fragment kodu, który można wysłać; które są dość ogólnego przeznaczenia i nadają się do ponownego użycia. Nazywa się to modułami elementów skompilowanych razem.
    • Trudno więc zobaczyć programy modułowe, które nie są ustrukturyzowane i odwrotnie; definicja techniczna jest nieco inna, ale w większości ustrukturyzowany kod może być modułowy i w inny sposób.
  3. Potem pojawiło się „programowanie obiektowe”, które jest dobrze zdefiniowane w literaturze. Zrozum, że programowanie obiektowe jest z definicji formą programowania strukturalnego. Nowa nazwa dla wszystkich kodów opartych na funkcjach, które są kodami strukturalnymi, ale NIE obiektowymi, są często nazywane programowaniem proceduralnym.

    • Tak więc zasadniczo ustrukturyzowany kod, w którym funkcje (lub procedury) dominują nad danymi, nazywa się proceduralnym, natomiast reprezentacja oparta na klasach i obiektach nazywa się obiektowym. Oba z definicji są również modułowe.

Wiele osób myśli - całe programowanie strukturalne (być może pomijanie obiektowe) jako programowanie imperatywne; Wydaje mi się, że dzieje się tak tylko z powodu braku jasnej definicji programowania imperatywnego - ale jest to błąd. Robisz programowanie strukturalne, kiedy nie robisz zbyt wielu programów koniecznych! Ale nadal mogę pisać wiele funkcji, a także wiele instrukcji goto w programie C lub FORTRAN do miksowania.

Aby sprecyzować swoje pytania:

Pierwsze pytanie : czysty język asemblerowy jest językiem imperatywnym, który NIE jest strukturalny ani proceduralny. (Posiadanie interpretacyjnego przepływu sterowania krok po kroku nie oznacza proceduralnego - ale podział funkcjonalności na funkcje sprawia, że ​​język jest proceduralny).

  • korekta * Większość nowoczesnych form montażu NALEŻY wspierać korzystanie z funkcji. W rzeczywistości wszystko, co jest możliwe w kodzie wysokiego poziomu, musi istnieć na niskim poziomie do działania. Chociaż tworzenie kodu procedur jest znacznie lepszą praktyką, możliwe jest pisanie zarówno kodu proceduralnego, jak i bezwzględnego. W przeciwieństwie do tego drugiego, jest łatwiejszy w utrzymaniu i łatwiejszy do zrozumienia (unikanie okropnego kodu spaghetti). Myślę, że istnieją skrypty powłoki / bash, które lepiej pasują do uznania, że ​​są absolutnie konieczne, ale nawet wtedy większość ma funkcje, programiści zdecydowanie rozumieją, ile mają wartości.

Drugie pytanie : Programowanie proceduralne jest FORMĄ programowania strukturalnego.


PREMIA

  • Według niektórych taksonomii podstawową klasyfikacją jest deklaratywny (lub język funkcjonalny) vs. imperatywny. Języki deklaratywne pozwalają na obliczenia bez opisywania ich przepływu sterowania, podczas gdy imperatywny jest tam, gdzie definiuje się jawny przepływ sterowania (krok po kroku). W oparciu o tę klasyfikację, programowanie imperatywne, dla niektórych może być super zestawem programowania strukturalnego, modułowego i OO. Zobacz: Programowanie funkcjonalne a OOP

  • Po Zorientowaniu obiektowym wymyślono inne paradygmaty programowania: zobacz tutaj, aby uzyskać więcej informacji: Jakie są różnice między programowaniem zorientowanym aspektowo, tematycznie i zorientowanym na rolę?

Dipan Mehta
źródło
1
Czy powiedziałbyś, że programowanie proceduralne jest koniecznie również programowaniem strukturalnym, podczas gdy przeciwieństwo nie jest prawdą (choć często tak jest)?
Daniel Scocco
2
Tak, powiedziałbym tak.
Dipan Mehta
1
W mojej odpowiedzi zdefiniowałem tryb rozkazujący vs. ustrukturyzowany - w którym programowanie rozkazujące jest pisane z krokowym wykonaniem i nie ma struktury. Jednak według niektórych definicji istnieje inna klasyfikacja; jest to klasyfikacja między językiem deklaratywnym (lub funkcjonalnym) a imperatywnym. Języki deklaratywne pozwalają na obliczenia bez opisywania ich przepływu sterowania, w przypadku gdy bezwzględnie konieczne jest zdefiniowanie jawnego przepływu sterowania (krok po kroku). W oparciu o tę klasyfikację, programowanie imperatywne, dla niektórych może być super-zestaw strukturalny. Niektórzy nie do końca podążają za tą definicją.
Dipan Mehta
Mam inne zdanie na temat definicji programowania strukturalnego. Programowanie strukturalne i programowanie modułowe to nie to samo. Zobacz definicję na końcu tej notatki. Ten sam link sugeruje, że Asembler ** jest ** strukturalnym językiem programowania! Odniesienie do definicji STP: en.wikipedia.org/wiki/Structured_programming - Emmad Kareem
NoChance
Czy „fizyczna forma pakietu” ... plik, czy katalog / archiwum plików? (A może nie, i jest to coś innego.)
n611x007
4

Pierwsze pytanie: Tak, kwalifikuje się wiele czysto obiektowych języków. Chociaż mają metody, które są bardzo zbliżone do funkcji, widzą te metody w kategoriach komunikatów i nie przywiązują wystarczającej wagi do wywołania języka proceduralnego.

Drugie pytanie: różnica ma często inny zakres. Możesz mieć funkcję z instrukcjami goto wszędzie, która będzie w stylu proceduralnym, ale nie w programowaniu strukturalnym. Z drugiej strony większość języków OP obsługuje i wspiera programowanie strukturalne, ale nie programowanie proceduralne.

Programowanie proceduralne opisuje globalną kolejność programu. Programy proceduralne to te, które są najskuteczniej zrozumiane, patrząc na ich wykresy połączeń. Programowanie strukturalne jest własnością lokalną, ma zastosowanie do użycia if i while w przeciwieństwie do goto.

Jako takie, te dwie właściwości są rozłączne, możesz mieć jedną bez drugiej.

Thiton
źródło
1
Jedynym lakmusowym testem na to, że jest proceduralny, jest to, że język zawiera procedury (funkcje lub metody ) i jest konieczny, tj. nie deklaratywny. Oznacza to, że większość języków OO, które nie są czysto funkcjonalne, byłaby proceduralna.
dietbuddha
1
@dietbuddha: Zgodnie z tą definicją Haskell kwalifikowałby się jako język proceduralny poprzez użycie monad. Wymagałbym pewnego polegania na procedurach, aby uczynić język proceduralnym.
thiton
Nie znam tak dobrze Haskell, ale pomyślałem, że Haskell jest czysto funkcjonalnym językiem, ponieważ zawiera efekty uboczne w Monadach.
dietbuddha,
2
Cóż, niektórzy twierdzą, Haskell nie jest czysto funkcjonalny, ponieważ pozwala ona żadnej interakcji ze światem zewnętrznym (lub ponieważ GHC rozszerzenia , unsafePerformIOpozwala sieje Havok). Inni żartują, że Haskell jest ich ulubionym imperatywnym językiem programowania. Ale faktem jest, że bardzo duży kod Haskell żyje IOw czystej postaci, nie używa niestandardowych luk w celu ukrycia efektów ubocznych i jest całkowicie funkcjonalny.
1
@thiton Nie zgadzam się. Monady są również konstrukcjami funkcjonalnymi; wydają się konieczne tylko ze względu na cukier składniowy Haskella („notacja”). Kiedy odsuwasz monady, ich funkcjonalna natura staje się oczywista. W przeciwieństwie do tego języki OO są naprawdę konieczne: u ich podstaw leżą sekwencyjne wykonywanie instrukcji.
Andres F.
2

większość popularnych języków ostatnich 50 lat została zaprojektowana wokół powszechnie stosowanej architektury komputerowej, zwanej architekturą Von Neumann , od jednego z jej twórców, Johna von Neumanna.

Języki te nazywane są językami rozkazującymi.

W komputerze von Neumaan zarówno dane, jak i programy są przechowywane w tej samej pamięci. Procesor, który wykonuje instrukcje, jest niezależny od pamięci. Dlatego instrukcje i dane muszą być przesyłane z pamięci do procesora. Wyniki operacji w CPU należy przenieść z powrotem do pamięci. Prawie wszystkie komputery cyfrowe zbudowane od lat 40. XX wieku oparte są na architekturze von Neumaan.

Anandmon
źródło
1
+1 nie jestem pewien, co to ma wspólnego z pytaniem, ale jest to interesująca odpowiedź.
Chuck Conway,
2
Co? Gdzie jest część o trybie rozkazującym a proceduralnym itp.?
bbqchickenrobot
Myślę, że chodzi tutaj o to, że sprzeczanie się o strukturę programu (imperatywną, deklaratywną, proceduralną, obiektową, funkcjonalną itp.) To konstrukcje językowe, a wszystkie programy są ostatecznie przetwarzane na maszynach architektury Von Neumanna. Jest to podobne do stwierdzenia, że ​​wszystkie języki Turing Complete są równoważne.
ChuckCottrill
2

Obawiam się, że żadna z dotychczas udzielonych odpowiedzi nie oddaje sedna tych koncepcji.

Imperatywne, proceduralne i strukturalne nie wykluczają się wzajemnie, skupiają się tylko na jednym aspekcie logiki modelowania.

Tryb imperatywny jest częścią przeciwstawną deklaratywnej Tryb imperatywny w zasadzie oznacza, że ​​mówisz komputerowi, co ma robić , wykonując szereg instrukcji, które udostępniasz. Z drugiej strony program deklaratywny mówi, co należy osiągnąć . Innymi słowy, zdefiniuj kroki kontra zdefiniuj wynik.

Programowanie proceduralne odnosi się do zdolności procesora (sprzętowego lub interpretera) do zawijania instrukcji w związki, przeskakiwania do takiego związku i powrotu do punktu po skoku po wykonaniu związku. Może się to wydawać trywialne i jak na dzisiejsze standardy, ale potrzebujesz trochę podstawowego wsparcia w maszynie, zanim to zrobisz: umiejętność skakania, pewnego rodzaju stosu do popychania adresu, który można otworzyć i przeskoczyć do niego później oraz wskaźnik stosu. Mikroprocesory wkrótce zaoferowały tę funkcję, ale możesz sobie wyobrazić prymitywny procesor, który jest w stanie wykonywać instrukcje podawane do niego sekwencyjnie, jak na przykład taśma perforująca lub procesor kart dziurkowanych.

Programowanie strukturalne to kolejny krok od umiejętności przejścia do innej instrukcji. Ostatecznie wszystko sprowadza się do skoków, ale jeśli możesz mieć skoki warunkowe, możesz zbudować podstawowe instrukcje przepływu sterującego, takie jak jeśli-to, dla, podczas gdy, powtarzaj-do i przełączaj. Stosowanie ich nazywa się programowaniem strukturalnym.

W każdym nowoczesnym środowisku programistycznym będziesz mieć do dyspozycji wszystkie powyższe elementy i przyjmiesz je za pewnik, więc nie mówimy już o nich jako takich. Różnice między językami od dawna zmieniły się na paradygmaty wyższego poziomu, takie jak programowanie obiektowe i programowanie funkcjonalne.

Programowanie deklaratywne wciąż nie jest powszechne, głównie dlatego, że zawsze będzie dotyczyło konkretnej domeny, przynajmniej do pewnego stopnia. Nie możesz mieć deklaratywnego języka ogólnego przeznaczenia. Właśnie dlatego wciąż tkwimy w tak zwanych językach trzeciej generacji, w których deklaratywne programowanie lub „modelowanie” byłoby uważane za czwartą generację.

Martin Maat
źródło