{"id":23361,"date":"2017-01-26T08:36:13","date_gmt":"2017-01-26T07:36:13","guid":{"rendered":"https:\/\/kmim.wm.pwr.edu.pl\/myszka\/?page_id=23361"},"modified":"2017-01-26T17:25:39","modified_gmt":"2017-01-26T16:25:39","slug":"09-tablice","status":"publish","type":"page","link":"https:\/\/kmim.wm.pwr.edu.pl\/myszka\/projekty\/fortran-dla-uzytkownikow-mes\/09-tablice\/","title":{"rendered":"09 Tablice"},"content":{"rendered":"<h2>Idea<\/h2>\n<p>\u201eZmienne skalarne\u201d s\u0142u\u017c\u0105 do przechowywania jednej warto\u015bci okre\u015blonego typu. Czasami jednak, w praktyce, mamy do czynienia z obiektami, kt\u00f3re s\u0105 bardziej z\u0142o\u017cone. Na przyk\u0142ad, \u017ceby opisa\u0107 po\u0142o\u017cenie punktu X w przestrzeni tr\u00f3jwymiarowej potrzebujemy trzech jego wsp\u00f3\u0142rz\u0119dnych. Teoretycznie, mo\u017cna by u\u017cy\u0107 do zapisu trzech zmiennych zwyk\u0142ych: <tt>X1<\/tt>, <tt>X2<\/tt>, <tt>X3<\/tt>. Je\u017celi teraz <tt>Y1<\/tt>, <tt>Y2<\/tt>, <tt>Y3<\/tt> b\u0119dzie opisywa\u0142 drugi punkt (Y) w przestrzeni i je\u017celi (traktuj\u0105c te punkty jako ko\u0144ce wektor\u00f3w zaczepionych w punkcie (0,0,0) zapragniemy wyliczy\u0107 ich iloczyn skalarny obliczenia b\u0119d\u0105 wygl\u0105da\u0142y jako\u015b tak:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;A = 0.\r\n2&nbsp;A = A + X1 * Y1\r\n3&nbsp;A = A + X2 * Y2\r\n4&nbsp;A = A + X3 * Y3<\/pre>\n<\/div>\n<p>(oczywi\u015bcie m\u00f3g\u0142bym zapisa\u0107 to w postaci \u201eprostszej\u201d: <tt>A = X1 * Y1 + X2 * Y2 + X3 * Y3<\/tt> ale nie zmienia to istoty sprawy; komputer ze wzgl\u0119du na swoj\u0105 konstrukcj\u0119 bardzo przypominaj\u0105c\u0105 konstrukcj\u0119 najprostszego kalkulatora czterodzia\u0142niowego i tak wszystkie obliczenia b\u0119dzie wykonywa\u0142 w czterech etapach. Pomy\u015blmy teraz o zmianie liczby wymiar\u00f3w: istota oblicze\u0144 ie zmieni si\u0119 gdy rozmiar przestrzeni zwi\u0119kszy si\u0119 do pi\u0119ciu, czy zmniejszy do 2. W ka\u017cdym przypadku b\u0119dziemy musieli zmodyfikowa\u0107 wyra\u017cenie (dodaj\u0105c lub odejmuj\u0105c cz\u0142ony). Zapiszmy teraz pierwszy blok kodu inaczej. Niech <tt>N<\/tt> oznacza rozmiar przestrzeni:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;N = 3\r\n2&nbsp;A = 0.\r\n3&nbsp;I = 1\r\n4&nbsp;A = A + XI * YI\r\n5&nbsp;I = I + 1\r\n6&nbsp;IF (I .LE. N) THEN GOTO 4 END IF<\/pre>\n<\/div>\n<p>Kod wyd\u0142u\u017cy\u0142 si\u0119 nieznacznie (6 zamiast 4 linijek) ale nabra\u0142 cech uniwersalno\u015bci \u2014 mo\u017ce by\u0107 stosowany dla dowolnego rozmiaru przestrzeni N. W linii 4 u\u017cy\u0142em symbolicznego zapisu kombinuj\u0105c nazw\u0119 zmiennej z dwu element\u00f3w: bazy (<tt>X<\/tt> albo <tt>Y<\/tt>) i numerka (<tt>I<\/tt>). Nie jest to zapis formalny. Aby go sformalizowa\u0107 trzeba wprowadzi\u0107 poj\u0119cie zmiennej z\u0142o\u017conej, mog\u0105cej przechowa\u0107 wi\u0119cej ni\u017c jedn\u0105 warto\u015b\u0107 tego samego typu). Zmienn\u0105 tak\u0105 konstruuje si\u0119 rezerwuj\u0105c w pami\u0119ci operacyjnej pewien obszar pami\u0119ci i u\u017cywaj\u0105c \u201eindeksu\u201d (w naszym wypadku <tt>I<\/tt>) do wskazywania kolejnych warto\u015bci w tym obszarze.<br \/>\n<i>Polecenie GOTO w powy\u017cszym przyk\u0142adzie nie jest do ko\u0144ca formalnie poprawne, ale nale\u017cy je rozumie\u0107 w spos\u00f3b nast\u0119puj\u0105cy: je\u017celi I &lt;= N nale\u017cy powt\u00f3rzy\u0107 wykonywanie kodu od linii oznaczonej numerem 4.<\/i> Polecenia te realizuj\u0105 ide\u0119 \u201ep\u0119tli\u201d, czyli fragmentu kodu, kt\u00f3ry powtarzany jest tak d\u0142ugo, jak d\u0142ugo spe\u0142niony jest pewien warunek.<\/p>\n<h2>Deklaracje tablic<\/h2>\n<p>Aby powy\u017cszy kod sformalizowa\u0107 musimy, po pierwsze, zadeklarowa\u0107 tablic\u0119 czyli tak\u0105 zmienn\u0105 z\u0142o\u017con\u0105, w kt\u00f3rej realizuje si\u0119 dost\u0119p do poszczeg\u00f3lnych element\u00f3w korzystaj\u0105c z \u201epomocniczego\u201d indeksu tablicy. Niestety, poprawnie zadeklarowa\u0107 tablice X i Y mo\u017cna na kilka sposob\u00f3w.<br \/>\nNajprostsza metoda b\u0119dzie taka:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;REAL X(3), Y(3)<\/pre>\n<\/div>\n<p>Kolejny spos\u00f3b b\u0119dzie nast\u0119puj\u0105cy: poniewa\u017c nazwy zmiennych zaczynaj\u0105 si\u0119 na litery <tt>X<\/tt> i <tt>Y<\/tt> \u2014 s\u0105 to (domy\u015blnie) zmienne typu <tt>REAL<\/tt>. Wystarczy zatem podkre\u015bli\u0107 jedynie, \u017ce s\u0105 to tablice i okre\u015bli\u0107 ich rozmiar:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;DIMENSION X(3), Y(3)<\/pre>\n<\/div>\n<p>Jeszcze inny spos\u00f3b jest nast\u0119puj\u0105cy: najpierw podajemy atrybuty zmiennej, p\u00f3\u017aniej deklarujemy zmienne zgodne z tymi atrybutami:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;REAL, DIMENSION (3) :: X, Y<\/pre>\n<\/div>\n<p>Je\u017celi chcemy napisa\u0107 program, kt\u00f3ry b\u0119dzie dosy\u0107 uniwersalny (to znaczy stosunkowo niezale\u017cny od rozmiaru <s>tablicy<\/s> przestrzeni <tt>N<\/tt>) mo\u017cna to zrobi\u0107 tak: najpierw definiujemy parametr <tt>N<\/tt> nadaj\u0105c mu oczekiwan\u0105 warto\u015b\u0107, a nast\u0119pnie deklarujemy w spos\u00f3b parametryczny tablice i wsz\u0119dzie w programie u\u017cywamy <tt>N<\/tt> gdy tylko odnosimy si\u0119 do wymiaru przestrzeni.<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;PARAMETER (N = 3)\r\n2&nbsp;REAL, DIMENSION (N) :: X, Y<\/pre>\n<\/div>\n<p>Teraz (o ile program napisany jest konsekwentnie) \u0142atwo przystosowywa\u0107 go do naszych potrzeb.<\/p>\n<p>Istnieje te\u017c mo\u017cliwo\u015b\u0107 (cho\u0107 to ju\u017c wy\u017csza szko\u0142\u0105 jazdy \u2014 umiej\u0119tno\u015b\u0107 konstruowania tablic \u201edynamicznych\u201d to u mnie jest wymaganiem na ocen\u0119 bardzo dobr\u0105) napisania programu, kt\u00f3ry b\u0119dzie ca\u0142kowicie niezale\u017cny od wymiaru przestrzeni. To znaczy b\u0119dziemy wymiar podawali w chwili uruchomienia programu.<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;REAL, ALLOCATABLE, DIMENSION (:) :: X, Y\r\n2&nbsp;INTEGER N\r\n3&nbsp;\u2026\r\n4&nbsp;READ(*,*) N\r\n5&nbsp;\u2026\r\n6&nbsp;ALLOCATE( X( N ) )\r\n7&nbsp;ALLOCATE( Y( N ) )\r\n8&nbsp;\u2026<\/pre>\n<\/div>\n<p>W programie tym pierwsza instrukcja informuje, \u017ce obiekty <tt>X<\/tt> i <tt>Y<\/tt> s\u0105 typu rzeczywistego (<tt>REAL<\/tt>), s\u0105 tablicami o nieokre\u015blonym rozmiarze (<tt>DIMENSION (:)<\/tt>) oraz, \u017ce przydzielimy im rozmiar p\u00f3\u017aniej (<tt>ALLOCATABLE<\/tt>).<br \/>\nNajpierw musimy zdefiniowa\u0107 warto\u015b\u0107 <tt>N<\/tt> (mo\u017cna j\u0105 przeczyta\u0107 z zewn\u0105trz albo wyliczy\u0107). Funkcja <tt>ALLOCATE<\/tt> s\u0142u\u017cy do przydzielenia obiektom o nazwach <tt>X<\/tt> i <tt>Y<\/tt> odpowiedniej ilo\u015bci pami\u0119ci operacyjnej.<br \/>\nDeklaracja tablicy dwuwymiarowej b\u0119dzie bardzo podobna. Najprostszy wariant jest taki:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;REAL V(5,3)<\/pre>\n<\/div>\n<p>i deklaruje dwuwymiarow\u0105 macierz prostok\u0105tn\u0105 o 5 wierszach i 3 kolumnach. Mo\u017cna r\u00f3wnie\u017c stworzy\u0107 macierz dynamiczn\u0105:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;REAL, ALLOCATABLE, DIMENSION(:,:) :: V\r\n2&nbsp;INTEGER M, N\r\n3&nbsp;\u2026\r\n4&nbsp;READ(*,*) M, N\r\n5&nbsp;ALLOCATE( V( M, N ) )\r\n6&nbsp;\u2026<\/pre>\n<\/div>\n<p>Indeks w tablicy zadeklarowanej jako:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;REAL X(3)<\/pre>\n<\/div>\n<p>musi by\u0107 liczb\u0105 ca\u0142kowit\u0105 z zakresu od 1 do 3 w\u0142\u0105cznie. Istnieje jednak mo\u017cliwo\u015b\u0107 zdefiniowania dolnej i g\u00f3rnej granicy indeksu dowolnie:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;REAL X(0:2)<\/pre>\n<\/div>\n<p>deklarujemy tablic\u0119 <tt>X<\/tt> o trzech sk\u0142adowych: <tt>X(0)<\/tt>, <tt>X(1)<\/tt>, <tt>X(2)<\/tt>. (NB w j\u0119zyku C wszystkie tablice standardowo maj\u0105 dolny indeks r\u00f3wny 0; nie mo\u017cna deklarowa\u0107 tablic o innej warto\u015bci dolnego indeksu). Dolna granica mo\u017ce r\u00f3wnie\u017c by\u0107 ujemna.<br \/>\nDo tablic jeszcze wr\u00f3cimy, bo to i trudny i wa\u017cny temat.<\/p>\n<h2>Dodatkowe polecenia u\u0142atwiaj\u0105ce obs\u0142ug\u0119 tablic<\/h2>\n<p>Realizacja idei tablic wymaga wprowadzenia (i opanowania) pewnych polece\u0144 nastawionych na efektywn\u0105 ich \u201eobs\u0142ug\u0119\u201d (na przyk\u0142ad \u201ewyzerowanie\u201d tablicy). Tradycyjnie, w j\u0119zyku Fortran, poleceniem takim by\u0142a zawsze instrukcja <tt>DO<\/tt>. Kiedy\u015b wygl\u0105da\u0142a ona tak:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;\tDO 10 I = 1, N\r\n2&nbsp;10\tX(I) = 0.<\/pre>\n<\/div>\n<p>Numerek wyst\u0119puj\u0105cy po poleceniu <tt>DO<\/tt> oznacza \u201ezakres\u201d kodu kt\u00f3ry ma by\u0107 wykonywany. (Ten zakres wskazany jest za pomoc\u0105 etykiety, czyli \u201enumerycznej\u201d przywieszki dodanej do linii kodu.) Natomiast konstrukcja <tt>I = 1, N<\/tt> m\u00f3wi, \u017ce zmienna <tt>I<\/tt> wewn\u0105trz p\u0119tli <tt>DO<\/tt> zmienia\u0107 si\u0119 b\u0119dzie od warto\u015bci 1 do <tt>N<\/tt> z (domy\u015blnym) krokiem 1. Gdy chcemy zmieni\u0107 krok, u\u017cywamy konstrukcji: <tt>DO 10 I = 1, N, 2<\/tt> (teraz b\u0119dzie to krok 2).<br \/>\nZmiany i unowocze\u015bnienia j\u0119zyka Fortran dokonane na przestrzeni wielu lat upodobni\u0142y j\u0119zyk do innych j\u0119zyk\u00f3w \u201estrukturalnych\u201d i wsp\u00f3\u0142czesna instrukcja <tt>DO<\/tt> (robi\u0105ca to samo wygl\u0105da inaczej:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;DO I = 1, N\r\n2&nbsp;  X(I) = 0.\r\n3&nbsp;END DO<\/pre>\n<\/div>\n<p>Instrukcje <tt>DO<\/tt> mo\u017cna \u201ezanurza\u0107\u201d jedn\u0105 w drugiej. \u017beby wyzerowa\u0107 tablic\u0119 dwuwymiarow\u0105 u\u017cyjemy konstrukcji:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;DO I = 1, M\r\n2&nbsp;  DO J = 1, N\r\n3&nbsp;    V(I, J) = 0.\r\n4&nbsp;  END DO\r\n5&nbsp;END DO<\/pre>\n<\/div>\n<p>\u201eWci\u0119cia\u201d kodu (realizowane za pomoc\u0105 odst\u0119p\u00f3w) s\u0105 nieobowi\u0105zkowe, ale zwi\u0119kszaj\u0105 jego czytelno\u015b\u0107.<br \/>\nInstrukcja <tt>DO<\/tt> nie jest jedyn\u0105, kt\u00f3ra u\u0142atwia organizowanie p\u0119tli. Inne pojawi\u0105 si\u0119 wkr\u00f3tce.<br \/>\nNa koniec, wreszcie, przyk\u0142ad, od kt\u00f3rego zacz\u0119li\u015bmy:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">1&nbsp;REAL, ALLOCATABLE, DIMENSION (:) :: X, Y\r\n2&nbsp;INTEGER N, I\r\n3&nbsp;REAL A\r\n4&nbsp;\u2026\r\n5&nbsp;READ(*,*) N\r\n6&nbsp;\u2026\r\n7&nbsp;ALLOCATE( X( N ) )\r\n8&nbsp;ALLOCATE( Y( N ) )\r\n9&nbsp;\u2026\r\n10&nbsp;! Tu gdzie\u015b nadajemy\/wczytujemy warto\u015bci elementom tablic X i Y\r\n11&nbsp;\u2026\r\n12&nbsp;A = 0.\r\n13&nbsp;DO I = 1, N\r\n14&nbsp;  A = A + X(I) * Y(I)\r\n15&nbsp;END DO<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h2>U\u017cycie tablic<\/h2>\n<p>Praktycznie \u017caden operator arytmetyczny nie pozwala wykonywa\u0107 operacji na ca\u0142ej tablicy. W operacjach arytmetycznych mog\u0105 bra\u0107 udzia\u0142 jedynie elementy tablicy. Do elementu tablicy odwo\u0142ujemy si\u0119 podaj\u0105c nazw\u0119 tablicy, a w nawiasach okr\u0105g\u0142ych indeks\/indeksy wskazuj\u0105ce jednoznacznie na wybrany element:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">X(I) * Y(I)<\/pre>\n<\/div>\n<p>Aby nada\u0107 warto\u015b\u0107 elementowi tablicy musi znale\u017a\u0107 si\u0119 on po lewej stronie znaku r\u00f3wno\u015bci:<\/p>\n<div class=\"zim-object\">\n<pre class=\"brush: fortran;\">X(I) = 5.<\/pre>\n<\/div>\n<p>Na programi\u015bcie le\u017cy obowi\u0105zek dbania, \u017ceby odwo\u0142ywa\u0142 si\u0119 do element\u00f3w \u201eistniej\u0105cych\u201d w tablicy. Niekt\u00f3re kompilatory mo\u017cna \u201epoprosi\u0107\u201d aby dodawa\u0142y kod sprawdzaj\u0105cy czy granice tablic nie s\u0105 przekraczane \u2014 zwi\u0119ksza to d\u0142ugo\u015b\u0107 kodu i spowalnia prac\u0119 programu.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Idea \u201eZmienne skalarne\u201d s\u0142u\u017c\u0105 do przechowywania jednej warto\u015bci okre\u015blonego typu. Czasami jednak, w praktyce, mamy do czynienia z obiektami, kt\u00f3re s\u0105 bardziej z\u0142o\u017cone. Na przyk\u0142ad, \u017ceby opisa\u0107 po\u0142o\u017cenie punktu X w przestrzeni tr\u00f3jwymiarowej potrzebujemy trzech jego wsp\u00f3\u0142rz\u0119dnych. Teoretycznie, mo\u017cna by u\u017cy\u0107 do zapisu trzech zmiennych zwyk\u0142ych: X1, X2, X3. Je\u017celi teraz Y1, Y2, Y3 b\u0119dzie &hellip; <a href=\"https:\/\/kmim.wm.pwr.edu.pl\/myszka\/projekty\/fortran-dla-uzytkownikow-mes\/09-tablice\/\" class=\"more-link\">Czytaj dalej <span class=\"screen-reader-text\">09 Tablice<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":23294,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"ngg_post_thumbnail":0,"footnotes":""},"class_list":["post-23361","page","type-page","status-publish","hentry"],"publishpress_future_action":{"enabled":false,"date":"2026-04-17 16:35:11","action":"change-status","newStatus":"draft","terms":[],"taxonomy":"language","extraData":[]},"publishpress_future_workflow_manual_trigger":{"enabledWorkflows":[]},"_links":{"self":[{"href":"https:\/\/kmim.wm.pwr.edu.pl\/myszka\/wp-json\/wp\/v2\/pages\/23361","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kmim.wm.pwr.edu.pl\/myszka\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/kmim.wm.pwr.edu.pl\/myszka\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/kmim.wm.pwr.edu.pl\/myszka\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kmim.wm.pwr.edu.pl\/myszka\/wp-json\/wp\/v2\/comments?post=23361"}],"version-history":[{"count":4,"href":"https:\/\/kmim.wm.pwr.edu.pl\/myszka\/wp-json\/wp\/v2\/pages\/23361\/revisions"}],"predecessor-version":[{"id":23365,"href":"https:\/\/kmim.wm.pwr.edu.pl\/myszka\/wp-json\/wp\/v2\/pages\/23361\/revisions\/23365"}],"up":[{"embeddable":true,"href":"https:\/\/kmim.wm.pwr.edu.pl\/myszka\/wp-json\/wp\/v2\/pages\/23294"}],"wp:attachment":[{"href":"https:\/\/kmim.wm.pwr.edu.pl\/myszka\/wp-json\/wp\/v2\/media?parent=23361"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}