Sekcje witryny
Wybór redaktorów:
- Wyprowadzanie części ikonki HTML obrazu
- Konfigurowanie dodatkowych szczegółów i dodatkowych informacji dla nomenklatury 1c, dodatkowe szczegóły i różnice informacyjne
- Co zrobić, gdy nie ma danych rejestracyjnych
- Zapytanie o selekcję danych (wzory) w programie MS EXCEL Excel selekcja według makra warunku
- Tymczasowy, jednorazowy e-mail Tymczasowy e-mail, strony pocztowe, rejestracja w mediach społecznościowych
- Co zrobić, jeśli komputer nie widzi telefonu przez port USB
- Jak zainstalować system Windows na komputerze Mac?
- Oprogramowanie konfiguracyjne Asus rt n16
- Jak sprawdzić bitowość systemu operacyjnego i procesora w systemie Windows
- Jak wyłączyć Zaporę systemu Windows: całkowita dezaktywacja i wyłączenie poszczególnych programów Jak całkowicie wyłączyć zaporę systemu Windows 7
Reklama
Jaka jest nazwa funkcji w programowaniu. Funkcje programowania |
Cel pracy: 1) przestudiować zasady opisu funkcji; 2) nabyć umiejętności wykorzystania funkcji podczas pisania programów w języku C++. Informacje teoretyczneGłównym modułem programów w C++ jest funkcja. Funkcjonować- logicznie wypełniony, zdecydowanie zaprojektowany fragment programu, który ma nazwę. Funkcje pozwalają dzielić duże zadania obliczeniowe na mniejsze. Każdy program w C++ koniecznie zawiera funkcję zwaną main, która jest treścią programu. W przypadku wszystkich innych funkcji, jeśli są obecne w programie, należy zadeklarować prototypy - schematyczne zapisy, które informują kompilator o nazwie i formie każdej funkcji w programie. Składnia prototypu funkcji z parametrami jest następująca: typ_wartości zwracanej nazwa_funkcji (lista_parametrów ze wskazaniem_typu); Funkcje w C++ są standardowe (bibliotekowe) i programowalne przez użytkownika. Funkcje standardoweOpisy standardowych funkcji znajdują się w plikach zawartych w programie za pomocą dyrektywy #include. Takie pliki nazywane są plikami nagłówkowymi; mają rozszerzenie h. Odwołanie się do nazwy funkcji w programie głównym nazywa się wywołaniem funkcji. Wywołanie funkcji skutkuje wykonaniem jakiejś akcji lub obliczeniem jakiejś wartości, która następnie zostaje wykorzystana w programie. y = grzech(x); //funkcja obliczania sinusa Definicja funkcjiOgólnie funkcje definiuje się w następujący sposób: typ_wartości zwracanej nazwa_funkcji (wpisz nazwa_parametru,..., wpisz nazwa_parametru) funkcja_ciała Programowalne funkcjeFunkcje, które programista tworzy samodzielnie, upraszczają proces pisania programów, ponieważ: pomagają uniknąć wielokrotnego programowania, ponieważ tej samej funkcji można używać w różnych programach; zwiększyć poziom modułowości programu, ułatwiając tym samym jego czytanie, wprowadzanie zmian i poprawianie błędów. Przykład9 .1. Stwórzmy funkcję, która wypisuje 65 znaków „*” z rzędu. Aby ta funkcja działała w pewnym kontekście, została ona dołączona do programu drukowania na papierze firmowym. Program składa się z funkcji: main() i stars(). // Papier firmowy #włączać stała int Limit=65; puste gwiazdy(pustka); // prototyp funkcji stars() cout<<"Moscow Institute of
Electronic Engineering"< // Definicja funkcji stars(). dla (liczba=1; liczba<=Limit; count++) Przyjrzeliśmy się przykładowi prostej funkcji, która nie ma argumentów i nie zwraca żadnych wartości. Spójrzmy na przykład użycia parametrów funkcji. Przykład9.
2.
Napiszmy funkcję space(),
którego argumentem będzie liczba spacji, które powinna wyświetlić ta funkcja. #zdefiniuj adres „Zelenograd” #define name „Moskiewski Instytut Inżynierii Elektronicznej” #define dział „Informatyka i Programowanie” stała int LIMIT=65; #włączać pusta spacja (liczba int); cout< spacje=(LIMIT - strlen(nazwa))/2; // Oblicz, ile // potrzebne są spacje cout< space((LIMIT - strlen(dział))/2); // argument - wyrażenie cout< //Definicja funkcji stars(). dla (liczba=1; liczba<=LIMIT; count++) //Definicja funkcji space(). pusta spacja (liczba całkowita) dla (liczba=1; liczba<=number; count++) Zmienna liczbowa nazywana jest argumentem formalnym. Zmienna ta przyjmuje wartość aktualnego argumentu w momencie wywołania funkcji. Innymi słowy, argument formalny jest zmienną w definicji wywoływanego podprogramu, oraz faktyczny argument jest konkretną wartością przypisaną tej zmiennej przez program wywołujący. Jeśli funkcja wymaga do komunikacji więcej niż jednego argumentu, możesz podać listę argumentów rozdzielonych przecinkami wraz z nazwą funkcji: void printnum(int i, int j) (czyt<<"Координаты
точек”<< i << j < Wartość wejściowa funkcji może zostać przetworzona dzięki obecności argument; Wartość wyjściowa jest zwracana za pomocą słowa kluczowego return. Użytkownicy, którym w zasadzie daleko do programowania, rzadko spotykają się z pojęciami funkcji i procedur, a kojarzą się one z czymś matematycznym i biurokratyczno-medycznym. W programowaniu wiele języków operuje tymi pojęciami, jednak nawet eksperci czasami nie są w stanie jasno zrozumieć różnicy między funkcją a procedurą. Podobnie jak w przypadku tego susła: jest tam, ale nikt go nie widzi. Zobaczmy, czy różnice są aż tak niewidoczne. Główną różnicą między funkcją a procedurą jest wynik, który zwraca. W rzeczywistości zarówno funkcje, jak i procedury są logicznie niepodzielnymi blokami tworzącymi kod programu. Funkcja zwraca wartość, procedura w większości języków programowania nie lub (na przykład w C) zwraca pustą wartość. W tym drugim przypadku (w C) procedurę uważa się za wersję podrzędną funkcji. Nagłówek funkcji zawiera słowo „funkcja”, identyfikator (nazwę właściwą funkcji), opcjonalnie listę parametrów i koniecznie typ wyniku. Treść funkcji musi zawierać operator, który przypisuje nazwę funkcji wartość, którą w rezultacie zwróci. Nagłówek procedury zawiera słowo „procedura”, identyfikator (nazwę procedury) i opcjonalnie listę parametrów. Wywołanie funkcji jest wykonywane jako część wyrażeń, gdzie te wyrażenia są używane; wywołanie procedury wymaga osobnej instrukcji. Procedurę wywołuje się wyłącznie z nazwy, natomiast nazwa funkcji jest powiązana z jej wartością. Na diagramach algorytmów wywołanie funkcji jest przedstawione w bloku wyjściowym lub w bloku procesu, wywołanie procedury jest przedstawione w specjalnym bloku „predefiniowanego procesu”. Podstawą każdego programu komputerowego są algorytmy wyrażone w postaci poleceń. Osoba pisząca kod mówi: weź to, zrób z tym to, to i tamto, a następnie wypisz wynik tam i idź odpocząć. Aby więc polecenia w programach nie łączyły się w jeden bałagan i mogły ze sobą współdziałać, grupuje się je w tzw. funkcje i procedury. Zapoznamy się z tymi pojęciami. Nazwy funkcji służą: 1) do tworzenia dokumentacji; 2) dla API, czyli interfejsu umożliwiającego połączenie z programem lub całym systemem operacyjnym dowolnej aplikacji. Warto zatem jeszcze raz przypomnieć, że nazwy te należy nadawać w sposób zrozumiały i w miarę możliwości adekwatny do wykonywanych czynności. Funkcje są więc swego rodzaju pojemnikami do grupowania algorytmów. Oni: Procedury to właściwie te same funkcje, choć „puste”, które nic nie zwracają (to jest ich główna różnica). Są to narzędzia pomocnicze przeznaczone do wykonywania rutynowych czynności, a także oszczędzające miejsce, wysiłek i czas. Poprzednie publikacje: Nie bez powodu nazwałem ten artykuł „Funkcjami jako integralna część programowania”, ponieważ bez nich, moim zdaniem, żaden język nie ma prawa istnieć. Co to jest? Funkcja jest głównym składnikiem dobrze napisanego programu. Nie tylko ułatwia czytanie kodu, ale także radykalnie zmienia ideę programowania strukturalnego. Za pomocą funkcji można ponownie wykorzystać poszczególne części programu przekazując im dowolne parametry. Nie można sobie wyobrazić żadnego poważnego programu bez tego cudu elementu programistycznego. Opowiem pokrótce jak to działa. Funkcja to blok instrukcji, który program może wywołać. Kiedy uzyskany zostanie dostęp do nagłówka tego bloku (nazwy funkcji), zostanie on wykonany i wykona pewne akcje określone przez programistę. Następnie blok ten zwraca otrzymaną wartość i przekazuje ją do programu głównego. Wyjaśnię to w praktyce.
Z grubsza rzecz biorąc, wygląda to tak. Wyjaśnię krótko. Tworzymy jakąś zmienną i przypisujemy do niej wynik wykonania funkcji myfunc, która z kolei oblicza wartość podniesienia jakiejś liczby do kwadratu. Funkcje nie są wykonywane natychmiast po uruchomieniu programu, lecz dopiero po ich wywołaniu. Może to być trochę mylące, ale tak właśnie jest. Aby wywołać funkcję, należy ją utworzyć. Chociaż istnieją również wbudowane funkcje. Na przykład to: cos, grzech, md5, liczba, abs i tak dalej. Aby je wywołać, wystarczy przypisać żądaną wartość do zmiennej.
Argument funkcji to wartość przekazywana do niej podczas jej wywoływania. Argumenty funkcji umieszcza się w nawiasach. Tworząc funkcję, określasz warunkowe nazwy argumentów. Następnie nazwy te można wykorzystać w treści funkcji jako zmienne lokalne. Wróćmy do funkcji, które sam tworzy użytkownik. Można to zrobić bardzo łatwo. Najpierw tworzone jest ciało funkcji: Funkcja hello() ( echo "Witaj, świecie!"; ) Potem do niej zadzwonimy. Co więcej, jeśli nie ma parametrów, po prostu umieszczamy nawiasy. Aby wywołać tę funkcję, używamy tylko linii: Witam();. Dowolna funkcja może również zwracać wartość za pomocą słowa zastrzeżonego powrót. Ta instrukcja zatrzymuje wykonywanie funkcji i wysyła wartość zwracaną do programu wywołującego. funkcja suma($pierwszy, $drugi) ($r=$pierwszy + $sekunda; zwróć $r;) echo sum(2,5); wynik wykonania programu będzie równy 7. Zmienne lokalne i globalne Podobnie jak w każdym innym języku programowania, istnieją zmienne dostępne tylko w ramach funkcji oraz zmienne dostępne w kodzie samego programu. Takie zmienne nazywane są odpowiednio lokalnymi i globalnymi. Wewnątrz funkcji nie można po prostu uzyskać dostępu do zmiennej utworzonej poza funkcją. Jeśli spróbujesz to zrobić, utworzysz nową zmienną o tej samej nazwie, ale lokalną dla tej funkcji. $per="Dima"; funkcja primer() // Wykonuje: wyświetlanie zmiennej lokalnej ( echo "Nazywam się ".$per; ) echo primer(); W takim przypadku na ekranie pojawi się fraza „Nazywam się”. Oznacza to, że zmienna $per została utworzona wewnątrz funkcji startera i domyślnie przypisano jej wartość zerową. Aby uniknąć takich ościeży, należy skorzystać z napędu światowy. Poprawmy odpowiednio powyższy kod: $per="Dima"; funkcja primer() // Wykonuje: wyświetlanie zmiennej globalnej ( global $per; echo "Nazywam się ".$per; ) echo primer(); Wszystko powinno już być w porządku - problem rozwiązany. Tylko nie zapominaj, że jeśli funkcja zmieni wartość zmiennej zewnętrznej, to taka zmiana będzie miała wpływ na cały program, dlatego trzeba ostrożnie używać tego operatora! Niektóre argumenty przekazywane do funkcji mogą być opcjonalne, dzięki czemu funkcja będzie mniej wymagająca. Poniższy przykład wyraźnie to ilustruje: … funkcja Font($text, $size=5) // Wykonaj: wyjściowy rozmiar czcionki ( echo " „.$tekst”."; ) czcionka("Witam Domyślnie rozmiar czcionki wynosi 5. Jeśli pominiemy drugi parametr funkcji, będzie on równy tej wartości. Zanim się pożegnam, chcę zwrócić uwagę na jedną radę. Polega na umieszczeniu wszystkich zapisanych funkcji w jednym pliku (np.function.php). A potem w pliku, w którym chcesz wywołać funkcję, wystarczy załączyć plikfunction.php i wszystko będzie gotowe do użycia. Dzięki temu znacznie łatwiej będzie zrozumieć logikę programu. Aby się połączyć użyj: include_once("funkcja.php"); require_once("funkcja.php"); Jeśli rozumiesz istotę zagadnienia omawianego w tym artykule, to jestem pewien, że z łatwością możesz wykorzystać funkcje w swoich programach. Po raz kolejny ma to na celu uczynienie ich bardziej elastycznymi i nadającymi się do ponownego użycia. To trzeci artykuł z serii „Teoria kategorii dla programistów”. W języku maszynowym dowolna kombinacja bajtów wytworzonych przez małpy zostanie zaakceptowana i wykonana. Jednak w językach wysokiego poziomu bardzo ceniona jest zdolność kompilatora do wykrywania błędów leksykalnych i gramatycznych. Wiele programów zostanie po prostu odrzuconych, a małpy zostaną bez bananów, ale reszta będzie miała większe szanse na sensowność. Sprawdzanie typu stanowi kolejną barierę przeciwko bezsensownym programom. Dodatkowo, podczas gdy w językach z typem dynamicznym niezgodności typów będą wykrywane tylko w czasie wykonywania, w językach z silnym typem i sprawdzaniem statycznym niezgodności typów są wykrywane w czasie kompilacji, co eliminuje wiele błędnych programów, zanim będą miały szansę zostać wykonane. Pytanie więc brzmi: czy chcemy, aby małpy były szczęśliwe, czy też stworzyliśmy odpowiednie programy? Zazwyczaj celem eksperymentu myślowego piszącej na klawiaturze jest stworzenie kompletnych dzieł Szekspira (przypis tłumacza: czyli Wojna i pokój Tołstoja). Sprawdzanie pisowni i gramatyki w pętli znacznie zwiększa Twoje szanse na sukces. Analogia sprawdzania typu idzie jeszcze dalej: kiedy Romeo zostanie uznany za człowieka, sprawdzanie typu zagwarantuje, że nie wyrosną mu liście i nie wyłapie fotonów za pomocą swojego potężnego pola grawitacyjnego. Jedynym poważnym argumentem, jaki słyszę przeciwko silnemu typowaniu statycznemu, jest to, że może ono odrzucić niektóre programy, które są poprawne semantycznie. W praktyce zdarza się to niezwykle rzadko (uwaga tłumacza: żeby nie było nieporozumień, zaznaczam, że autor nie wziął pod uwagę, lub się z tym nie zgadza, że stylów jest wiele, a kaczy typ, znany programistom w językach skryptowych, też ma prawo do życia Z drugiej strony typowanie kaczkowe jest możliwe w systemie ścisłych typów poprzez szablony, cechy, klasy typów, interfejsy, technologii jest wiele, więc opinii autora nie można uznać za całkowicie błędną.) w każdym razie każdy język zawiera swego rodzaju backdoora, który pozwala ominąć system typów, gdy jest to naprawdę konieczne. Nawet Haskell ma unsafeCoerce. Ale takich projektów należy używać mądrze. Gregor Samsa, postać grana przez Franza Kafkę, łamie system typów, zamieniając się w gigantycznego chrząszcza i wszyscy wiemy, jak to się skończy (uwaga tłumacza: źle:). Innym argumentem, który często słyszę, jest to, że mocne pisanie stanowi zbyt duże obciążenie dla programisty. Mogę współczuć temu problemowi, ponieważ sam napisałem kilka deklaracji iteratorów w C++, z tą różnicą, że istnieje technologia wnioskowania o typie, która pozwala kompilatorowi wnioskować o większości typów z kontekstu, w którym są używane. W C++ możesz zadeklarować zmienną auto, a kompilator wywnioskować jej typ za Ciebie. W Haskell, z wyjątkiem rzadkich przypadków, adnotacje typu są opcjonalne. Programiści i tak zwykle z nich korzystają, ponieważ typy mogą wiele powiedzieć o semantyce kodu, a deklaracje typów pomagają zrozumieć błędy kompilacji. Powszechną praktyką w Haskell jest rozpoczynanie projektu od opracowania typów. Później adnotacje typów stanowią podstawę implementacji i stają się komentarzami gwarantowanymi przez kompilator. Silne pisanie statyczne jest często używane jako wymówka, aby nie testować kodu. Czasami usłyszysz, jak programiści Haskella mówią: „Jeśli kod się kompiluje, jest on poprawny”. Oczywiście nie ma gwarancji, że program o poprawnym typie jest poprawny w sensie generowania poprawnych wyników. W wyniku takiego podejścia w wielu badaniach Haskell nie wyprzedził znacząco innych języków pod względem jakości kodu, jak można by się spodziewać. Wydaje się, że w środowisku komercyjnym potrzeba naprawiania błędów istnieje tylko do pewnego poziomu jakości, który jest głównie związany z ekonomiką tworzenia oprogramowania i tolerancją użytkownika końcowego, a ma bardzo niewiele wspólnego z językiem programowania lub rozwojem metodologia. Lepszym miernikiem byłoby zmierzenie liczby projektów opóźnionych w stosunku do harmonogramu lub zrealizowanych ze znacznie ograniczoną funkcjonalnością. Teraz, jeśli chodzi o twierdzenie, że testy jednostkowe mogą zastąpić silne pisanie. Przyjrzyjmy się powszechnej praktyce refaktoryzacji w językach silnie typowanych: zmianie typu argumentu na funkcję. W językach silnie typowanych wystarczy zmienić deklarację tej funkcji, a następnie poprawić ewentualne błędy kompilacji. W językach słabo typowanych fakt, że funkcja oczekuje teraz innych danych, nie może być przypisany wywołującemu. Testowanie jednostkowe może wychwycić niektóre niespójności, ale testowanie jest prawie zawsze procesem probabilistycznym, a nie deterministycznym (Uwaga tłumacza: być może chodziło im o zestaw testów: nie uwzględnia się wszystkich możliwych danych wejściowych, ale pewną reprezentatywną próbę.) Testowanie jest kiepskim substytutem dowodu poprawności. Zbiory mogą być skończone lub nieskończone. Typ String, który jest zasadniczo synonimem listy Char, jest przykładem nieskończonego zbioru. Kiedy deklarujemy x jako liczbę całkowitą: Istnieją pewne subtelności, które utrudniają utożsamianie typów z zestawami. Istnieją problemy z funkcjami polimorficznymi, które mają definicje cykliczne, a także z faktem, że nie można mieć zbioru wszystkich zbiorów; ale jak obiecałem, nie będę ścisłym matematykiem. Ważne jest to, że istnieje kategoria zbiorów zwana Zestawem i będziemy z nią pracować. Zestaw to szczególna kategoria, ponieważ możemy zajrzeć do wnętrza jego obiektów, co pomoże nam wiele zrozumieć intuicyjnie. Wiemy na przykład, że zbiór pusty nie ma elementów. Wiemy, że istnieją specjalne zbiory jednego elementu. Wiemy, że funkcje odwzorowują elementy jednego zbioru na elementy innego. Potrafią zmapować dwa elementy w jeden, ale nie jeden element na dwa. Wiemy, że funkcja tożsamości odwzorowuje każdy element zbioru na siebie i tak dalej. Planuję stopniowo zapomnieć o wszystkich tych informacjach i zamiast tego wyrazić wszystkie te pojęcia w formie czysto kategorycznej, to znaczy w kategoriach obiektów i strzałek. W idealnym świecie moglibyśmy po prostu powiedzieć, że typy w Haskell to zbiory, a funkcje w Haskell to funkcje matematyczne pomiędzy. Jest tylko jeden mały problem: funkcja matematyczna nie wykonuje żadnego kodu — zna tylko odpowiedź. Funkcja w Haskell musi obliczyć odpowiedź. Nie stanowi to problemu, jeśli odpowiedź można uzyskać w skończonej liczbie kroków, niezależnie od ich wielkości. Istnieją jednak pewne obliczenia wymagające rekurencji, które mogą nigdy się nie zakończyć. Nie możemy po prostu zabronić funkcji niekończących się w Haskell, ponieważ rozróżnienie, czy funkcja kończy się, czy nie – słynny problem zatrzymania – jest nierozwiązywalne. Dlatego informatycy wpadli na genialny pomysł (lub brudny hack, w zależności od punktu widzenia), aby rozszerzyć każdy typ o specjalną wartość zwaną dołem (Nota tłumacza: to określenie (na dole) brzmi po rosyjsku trochę głupio, jeśli ktoś zna dobrą opcję, proszę o sugestię.), co jest oznaczone _|_ lub w Unicode ⊥. Ta „wartość” odpowiada niekompletnemu obliczeniu. Zatem funkcja zadeklarowana jako: Co ciekawe, gdy już zaakceptujesz wartość Bottom w systemie typów, wygodnie jest traktować każdy błąd wykonania jako wartość dolną, a nawet pozwolić funkcji na jawne zwrócenie wartości Bottom. To drugie jest zwykle wykonywane przy użyciu niezdefiniowanego wyrażenia: Funkcje, które mogą zwrócić dół, nazywane są częściowymi, w przeciwieństwie do zwykłych funkcji, które zwracają prawidłowe wyniki dla wszystkich możliwych argumentów. Ze względu na dół kategoria typów i funkcji Haskell nazywa się Hask, a nie Set. Z teoretycznego punktu widzenia jest to źródło niekończących się komplikacji, więc w tym momencie użyję mojego noża rzeźniczego i skończę z tym. Z pragmatycznego punktu widzenia można zignorować funkcje niekończące się i dno i potraktować Haska jako pełnoprawny zbiór. Istnieją formalne sposoby opisu semantyki języka, ale ze względu na ich złożoność stosuje się je głównie w przypadku uproszczonych języków akademickich, a nie prawdziwych gigantów programowania przemysłowego. Jedno z tych narzędzi nazywa się semantyką operacyjną i opisuje mechanikę wykonywania programu. Definiuje sformalizowanego, wyidealizowanego interpretatora. Semantykę języków przemysłowych, takich jak C++, opisuje się zazwyczaj za pomocą nieformalnego rozumowania, często w kategoriach „abstrakcyjnej maszyny”. Problem polega na tym, że bardzo trudno jest udowodnić cokolwiek w przypadku programów korzystających z semantyki operacyjnej. Aby pokazać właściwość programu, zasadniczo trzeba go „przepuścić” przez wyidealizowany interpreter. Nie ma znaczenia, że programiści nigdy formalnie nie udowadniają poprawności. Zawsze „myślimy”, że piszemy właściwe programy. Nikt nie siedzi przy klawiaturze i nie mówi: „Och, napiszę tylko kilka linijek kodu i zobaczę, co się stanie”. (nota tłumacza: och, gdyby tylko...) Wierzymy, że napisany przez nas kod wykona określone działania, które przyniosą oczekiwane rezultaty. Zwykle jesteśmy bardzo zaskoczeni, jeśli tak nie jest. Oznacza to, że tak naprawdę myślimy o programach, które piszemy i zazwyczaj robimy to poprzez uruchomienie interpretera w naszych głowach. Po prostu bardzo trudno jest śledzić wszystkie zmienne. Komputery są dobre w wykonywaniu programów, ludzie nie! Gdyby tak było, nie potrzebowalibyśmy komputerów. Ale istnieje alternatywa. Nazywa się to semantyką denotacyjną i opiera się na matematyce. W semantyce denotacyjnej dla każdej konstrukcji językowej opisana jest interpretacja matematyczna. Zatem jeśli chcesz udowodnić właściwość programu, wystarczy, że udowodnisz twierdzenie matematyczne. Myślisz, że dowodzenie twierdzeń jest trudne, ale tak naprawdę my, ludzie, tworzymy metody matematyczne od tysięcy lat, więc istnieje wiele zgromadzonej wiedzy, którą można wykorzystać. Ponadto w porównaniu z twierdzeniami dowodzonymi przez zawodowych matematyków, problemy, które napotykamy w programowaniu, wydają się być dość proste, jeśli nie trywialne. (Nota tłumacza: dla dowodu autor nie stara się urazić programistów.) Rozważmy definicję funkcji silni w Haskell, języku, który łatwo nadaje się do semantyki denotacyjnej: Jedną z istotnych zalet posiadania matematycznego modelu programowania jest możliwość przeprowadzenia formalnego dowodu poprawności oprogramowania. Może to nie wydawać się tak ważne, gdy piszesz oprogramowanie konsumenckie, ale istnieją obszary programowania, w których koszty awarii mogą być ogromne lub w których zagrożone jest życie ludzkie. Ale nawet pisząc aplikacje internetowe dla systemu opieki zdrowotnej można docenić fakt, że funkcje i algorytmy ze standardowej biblioteki Haskell są dostarczane wraz z dowodami poprawności. Funkcję matematyczną możemy zaimplementować w języku programowania: taka funkcja po podaniu wartości wejściowej obliczy wartość wyjściową. Funkcja podnosząca liczbę do kwadratu prawdopodobnie pomnoży wartość wejściową przez siebie. Zrobi to za każdym razem, gdy zostanie wywołane i gwarantuje, że zwróci ten sam wynik za każdym razem, gdy zostanie wywołane z tym samym argumentem. Kwadrat liczby nie zmienia się wraz z fazami księżyca. Co więcej, obliczenie kwadratu liczby nie powinno skutkować podarowaniem psu smacznego przysmaku. „Funkcji”, która to robi, nie można łatwo modelować za pomocą funkcji matematycznej. W językach programowania funkcje, które zawsze dają ten sam wynik na tych samych argumentach i nie mają skutków ubocznych, nazywane są czystymi. W czystym języku funkcjonalnym, takim jak Haskell, wszystkie funkcje są czyste. Ułatwia to określenie semantyki denotacyjnej tych języków i modelowanie ich za pomocą teorii kategorii. W przypadku innych języków zawsze możesz ograniczyć się do czystego podzbioru lub osobno pomyśleć o skutkach ubocznych. Później zobaczymy, jak monady pozwalają nam modelować wszelkiego rodzaju efekty przy użyciu wyłącznie czystych funkcji. W rezultacie nic nie tracimy ograniczając się do funkcji matematycznych. (Pamiętaj, że a jest zmienną typu, która może być dowolnego typu.) Ta nazwa nie jest przypadkowa. Istnieje głębsza interpretacja typów i funkcji w kategoriach logiki zwana izomorfizmem Curry'ego-Howarda. Typ Pustki reprezentuje nieprawdziwość, a funkcja absurdalna reprezentuje twierdzenie, że coś wynika z fałszu, jak w łacińskim wyrażeniu „ex falso sequitur quodlibet”. (Nota tłumacza: wszystko wynika z fałszu.) Następny jest typ odpowiadający zbiorowi singletonów. Jest to typ, który ma tylko jedną możliwą wartość. To znaczenie to po prostu „istnieje”. Być może nie rozpoznasz go od razu, ale w C++ jest on nieważny. Pomyśl o funkcjach od i do tego typu. Zawsze można wywołać funkcję void. Jeśli jest to czysta funkcja, zawsze zwróci ten sam wynik. Oto przykład takiej funkcji: A co z funkcjami, które zwracają wartość void lub, w Haskell, zwracają ją? W C++ takich funkcji używa się do efektów ubocznych, ale wiemy, że takie funkcje nie są funkcjami rzeczywistymi w matematycznym znaczeniu tego słowa. Czysta funkcja, która zwraca jeden, nic nie robi: odrzuca swój argument. Matematycznie funkcja ze zbioru A do zbioru singletonowego odwzorowuje każdy element na pojedynczy element tego zbioru. Dla każdego A istnieje dokładnie jedna taka funkcja. Oto dla liczby całkowitej: Funkcje, które można zdefiniować za pomocą tego samego wzoru dla dowolnego typu, nazywane są parametrycznie polimorficznymi. Można zaimplementować całą rodzinę takich funkcji za pomocą jednego równania, używając parametru zamiast konkretnego typu. Jak wywołać funkcję polimorficzną z dowolnego typu na jeden? Oczywiście nazwiemy to jednostką: Funkcje Pure Bool po prostu wybierają dwie wartości z typu docelowego, jedną odpowiadającą True i jedną odpowiadającą False. Funkcje w języku Bool nazywane są predykatami. Na przykład biblioteka Data.Char w Haskell zawiera wiele predykatów, takich jak IsAlpha lub isDigit. Podobna biblioteka istnieje w C++ |
Popularny:
Nowy
- Konfigurowanie dodatkowych szczegółów i dodatkowych informacji dla nomenklatury 1c, dodatkowe szczegóły i różnice informacyjne
- Co zrobić, gdy nie ma danych rejestracyjnych
- Zapytanie o selekcję danych (wzory) w programie MS EXCEL Excel selekcja według makra warunku
- Tymczasowy, jednorazowy e-mail Tymczasowy e-mail, strony pocztowe, rejestracja w mediach społecznościowych
- Co zrobić, jeśli komputer nie widzi telefonu przez port USB
- Jak zainstalować system Windows na komputerze Mac?
- Oprogramowanie konfiguracyjne Asus rt n16
- Jak sprawdzić bitowość systemu operacyjnego i procesora w systemie Windows
- Jak wyłączyć Zaporę systemu Windows: całkowita dezaktywacja i wyłączenie poszczególnych programów Jak całkowicie wyłączyć zaporę systemu Windows 7
- Potężny konwerter plików HTML na Doc, PDF, Excel, JPEG, tekst Korzystanie z programu Total HTML Converter