440 likes | 573 Views
ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΤΜΗΜΑ ΜΗΧΑΝΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΒΙΟΜΗΧΑΝΙΑΣ. ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ. Ι. Σαρρής , sarris@uth.gr , τηλ . 2421074090. Διάλεξη 1: Δυναμικά δεδομένα στη FORTRAN 90. Εαρινό εξάμηνο 2008. Οργάνωση παρουσίασης. Θα δούμε την σύνταξη και την χρήση των δυναμικών πινάκων
E N D
ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΤΜΗΜΑ ΜΗΧΑΝΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΒΙΟΜΗΧΑΝΙΑΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ι. Σαρρής,sarris@uth.gr, τηλ. 2421074090 Διάλεξη 1: Δυναμικά δεδομέναστη FORTRAN 90 Εαρινό εξάμηνο 2008
Οργάνωση παρουσίασης • Θα δούμε την σύνταξη και την χρήση των δυναμικών πινάκων • Την εισαγωγή των δυναμικών πινάκων στις διαδικασίες • Τους παράγωγους τύπους δεδομένων • Τους δείκτες και την χρήση τους
Δυναμικοί πίνακες (συνέχεια) Επίσης, IF(.NOT.ALLOCATED(B))ALLOCATE(B(-10:10,3))
Παράδειγμα REAL,ALLOCATABLE::X(:,:) ... ALLOCATE(X(10,2),STAT=IERR) IF(IERR).GT.0)CALLHANDLER X=0.0 ... DEALLOCATE(X) ... ALLOCATE(X(-10:10),5),STAT=JERR)
Διαδικασίες και πίνακες (συνέχεια)
Παράδειγμα PROGRAM automat IMPLICITNONE REAL, ALLOCATABLE ::A(:,:) INTEGER ::i,n,m READ*,n,m ALLOCATE(A(n,m),STAT=IERR) IF(IERR).GT.0)CALLHANDLER A = 1. CALL auto(A,n,m) DEALLOCATE(A) CONTAINS SUBROUTINE auto(c,n,m) INTEGER, INTENT(IN) ::n, m REAL, INTENT(IN) ::c(n,m)!εικονικός INTEGER ::i,j REAL ::b(n,m) !αυτόματος FORALL(i=1:n,j=1,m) b(i,j)=c(i,j)*c(i,j) END FORALL ENDSUBROUTINE auto ENDPROGRAM automat
Παράδειγμα INTEGER,ALLOCATABLE, DIMENSION(:)::X ALLOCATE(X(3),STAT=IERR) IF(IERR).GT.0)CALLHANDLER X=(/1,2,3/); PRINT *, X !Τυπώνει: 1 2 3 n = SIZE(X) X=test(x,n); PRINT *, X !Τυπώνει: 1 49 IF (ALLOCATED(X)) DEALLOCATED (X) CONTAINS FUNCTION test(x,n) RESULT(y) INTEGER, INTENT(IN) ::n, x(:) !υποθετικής μορφής INTEGER, DIMENSION(n) ::y !αυτόματος y=x*x ENDFUNCTION test END
Παράγωγοι τύποι δεδομένων (συνέχεια)
Παράγωγοι τύποι δεδομένων (συνέχεια)
Παράγωγοι τύποι δεδομένων (συνέχεια)
Παράδειγμα IMPLICITNONE TYPE IDEAL REAL ::VOLUME,PRESSURE,T CHARACTER(11) ::HEADER ENDTYPE IDEAL TYPE (IDEAL) :: C(5) ! Ο πίνακας C είναι τύπου IDEAL REAL ::CONSTANT INTEGER ::I REAL,PARAMETER ::R=0.0820556 C%HEADER=(/’PRESSURE’,’VOLUME’,’TEMPERATURE’,’’,’’/) C(1)%PRESSURE=15; C%T=298 C%VOLUME =(/100,80,60,40,20/) CONTANT = C(1)%PRESSURE*C(1)%VOLUME C(:)%PRESSURE=CONSTANT/C(:)%VOLUME ! Τυπώνουμε την επικεφαλίδα: WRITE(*,’(X,3A11,)’) (C(I)%HEADER,I=1,3) ! Τυπώνουμε τις τιμές: DO I=1,5 WRITE(*,’(F6.2,6X,F5.1,8X,F5.1)’) C(I)%PRESSURE, C(I)%VOLUME, C(I)%T END DO END
Παράδειγμα INTEGER, POINTER ::P INTEGER, TARGET ::X=10, Y=0 P=>X !P=X=10, Y=0, P συσχετισμένος με X Χ=11 !Χ=11 και P=11 Χ=10 !P=10 και X=10 Y=P !Y=X=10 P=>Y !P=Y=10, X=10, P συσχετισμένος με Y P=>20 !P=Y=20, X=10 ! P=>10 ! Λάθος ! P=>y+1 ! Λάθος P=10 ! σωστό P=y+1 ! σωστό NULLIFY(P) ! P μη συσχετισμένος. Δεν έχει τιμή! END
Ανάθεση σε δείκτες (συνέχεια) • Όταν στόχος είναι ένας άλλος δείκτης, τότε η συσχέτιση γίνεται με το στόχο του. Δηλαδή στο παράδειγμα ο ‘P2’ δείχνει το ‘X’ και θα συνεχίσει να το δείχνει ακόμη και όταν ο ‘P1’ θα δείξει το ‘Y’. INTEGER, POINTER ::P1, P2 !Με στόχο δείκτη INTEGER, TARGET ::X=10, Y=0 P1=>X ! P1=X=10, Y=0, P2 αόριστος P2=>Y ! P2=Y=0, P2 συσχετισμένος με το Y P2=>P1 ! P2=X=10, Y=0, P2 συσχετισμένος με το X P1=>Y ! P1=Y=0, P1 συσχετισμένος με το Y END
Παράδειγμα INTEGER, POINTER ::P1, P2 INTEGER, TARGET ::X=10, Y=0 LOGICAL ::status P1=>X status=ASSOCIATED(P1) ! 1) .TRUE. status=ASSOCIATED(P1,X) ! 2) .TRUE. status=ASSOCIATED(P1,Y) ! 3) .FALSE. status=ASSOCIATED(P2) ! 4) .FALSE. P2=>Y status=ASSOCIATED(P2) ! 5) .TRUE. P2=>P1 status=ASSOCIATED(P2,P1) ! 6) .TRUE. status=ASSOCIATED(P1,P2) ! 7) .TRUE. status=ASSOCIATED(P2,Y) ! 8) .FALSE. P1=>Y status=ASSOCIATED(P2,P1) ! 10) .TRUE. status=ASSOCIATED(P2,X) ! 11) .TRUE. END
Δέσμευση μνήμης INTEGER, POINTER ::P, ARRAY_OF_P(:) INTEGER ::N=10 ALLOCATE(P,ARRAY_OF_P(N)) . . DEALLOCATE(P,ARRAY_OF_P) • Στην παραπάνω περίπτωση ο ‘P’ συσχετίζεται με μια περιοχή μνήμης 4 bytes ‘ARRAY_OF_P’ με μια περιοχή μνήμης 4Χ10 bytes. • Χρειάζεται προσοχή για να μην υπάρξουν διαρροές μνήμης INTEGER, POINTER ::P1(:), P2(:) INTEGER ::N=10 ALLOCATE(P1(N),P2(N)) NULLIFY(P1) P1=>P2 DEALLOCATE(P2) END Ο P1 δεν συσχετίζεται με τη μνήμη, που όμως παραμένει δεσμευμένη Ο P1 συσχετίζεται με τον P2. Στη συνέχεια όμως η μνήμη αποδεσμεύεται και ο P1 μένει αιωρούμενος με απρόβλεπτα αποτελέσματα
Δείκτες πινάκων Οι δείκτες μπορούν να χρησιμοποιηθούν και σαν δυναμικά ψευδώνυμα ολόκληρων πινάκων ή τμημάτων τους. REAL, TARGET ::A(6,6) REAL, POINTER ::cntr(:), row(:) cntr=> A(3:4,3:4); row=A(3:) REAL, TARGET ::A(-3:2) REAL, POINTER ::row(:) row=>A ! a) row (-3:2) row=A(:) ! b) row (1:6) row=A(0::2) ! c) row (1:2)
Δείκτες πινάκων(συνέχεια) • Αν ο δείκτης συσχετίζεται με τμήμα ενός πίνακα, το κάτω όριο του είναι 1 και το άνω όριο ίσο με την έκταση του τμήματος, έστω και αν το τμήμα είναι ίσο με τον πίνακα. • Αν ο δείκτης σχετίζεται με ολόκληρο πίνακα, τα όρια και οι ενδεικτές του είναι ίδια με του πίνακα. • Δεν μπορούμε να χρησιμοποιήσουμε διανυσματικούς ενδεικτές για να προσδιορίσουμε τμήμα πίνακα που σχετίζεται με δείκτη. Ο μόνος τρόπος είναι οι τριάδες. • Οι πίνακες δεικτών είναι εξ ορισμού ALLOCATABLEκαι δεν χρειάζονται DEALLOCATE.
Δείκτες και παράγωγοι τύποι • Οι δείκτες μπορούν να είναι συστατικά παραγώγων τύπων, ή να συσχετιστούν με μεταβλητές παραγώγων τύπων ή με στοιχεία τους, όπως ακριβώς και με τις μεταβλητές βασικού τύπου. PROGRAM pointers IMPLICIT NONE TYPE example REAL, POINTER:: P(:) ENDTYPE example INTEGER ::I, J, N TYPE(example)::X(3) DO I=1,3 READ*, N ALLOCATE(X(I)%P(N)) !κάθε φορά διαφορετικό n X(I)%P=(/(J,J=1,N)/) PRINT ‘(10F5.2)’, X(I)%P ENDDO END PROGRAM pointers
Δείκτες και διαδικασίες • Οι δείκτες μπορούν να χρησιμοποιηθούν σαν εικονικές μεταβλητές διαδικασιών ή σαν παράμετροι του ορίσματος της κλήσης τους. • Το αποτέλεσμα μιας διαδικασίας τύπου FUNCTION μπορεί να είναι δείκτης • Περιορισμοί: • Η αντίστοιχη παράμετρος κλήσης πρέπει να είναι επίσης δείκτης του ίδιου τύπου, είδους και τάξης. • Ένας εικονικός δείκτης δεν μπορεί να έχει την ιδιότητα INTENT και οι διαδικασίες δεν μπορούν να είναι PURE ή ELEMENTAL. • Οι διαδικασίες που χρησιμοποιούν εικονικούς δείκτες ή στόχους πρέπει να έχουν ρητή διεπιφάνεια (θα δούμε γιατί όταν θα μιλήσουμε για τα αντικείμενα). • Τέλος, αν μια παράμετρος κλήσης της διαδικασίας είναι δείκτης, ενώ ο αντίστοιχος εικονικός όρος της διαδικασίας δεν είναι, τότε ο εικονικός όρος συσχετίζεται με το στόχο του δείκτη (ο δείκτης απαναφέρεται)
Παράδειγμα PROGRAMpointers IMPLICITNONE REAL, DIMENSION(0:100)::X REAL, DIMENSION(:), POINTER ::P INTEGER::I X=0.; X(::40)=(/(I,I=1,3)/) CALL nonzero(X,P) PRINT*, P; PRINT*,SIZE(P) CONTAINS SUBROUTINE nonzero(a,b) REAL, DIMENSION(:) ::a REAL, DIMENSION(:), POINTER ::b INTEGER:: i, j, n n = COUNT(a>1.E-7) ALLOCATE(b(n)) DO j = 1, SIZE(a) IF(a(j)<1.E-7) CYCLE i=i+1 b(i)=a(j) END DO ENDPROGRAMpointers
Λίστες Οι δείκτες μας δίνουν τη δυνατότητα δημιουργίας δυναμικών δομών όπως οι συνδεδεμένες λίστες (ουρές, σωρούς, δενδριτικές δομές, κλπ) Οι δομές αυτές μας δίνουν την δυνατότητα της κατά βούλησης αύξησης και μείωσης του μεγέθους τους κατά την διάρκεια της εκτέλεσης. TYPE list INTEGER ::value TYPE (list), POINTER::next ! Αναδρομική δήλωση ENDTYPE list
Παράδειγμα reading:DO READ(*,*) number; IF(number==0) EXIT ALLOCATE(last%next, STAT=status) IF(status/=0) STOP ‘NOT ENOUGH MEMORY’ last =>last%next last%next =>NULL() last%value = number ENDDO reading ENDIF printing:DOWHILE(ASSOCIATED(first)) PRINT*, first%value first=>first%next ENDDO printing ENDPROGRAM linkedlist PROGRAM linkedlist IMPLICITNONE TYPE list INTEGER ::value TYPE (list), POINTER::next ENDTYPE list TYPE(list),POINTER::first,last INTEGER:: number, status NULLIFY(first,last) READ*, number IF(number/=0) THEN ALLOCATE(first, STAT=status) IF(status/=0) STOP ‘NOT ENOUGH MEMORY’ last =>first last%next =>NULL() last%value = number
NULL NULL first last Λίστες(συνέχεια) • Η περιγραφή του τύπου list είναι αναδρομική • Δεν έχουμε δηλώσει πουθενά το μέγεθος της λίστας • Η δημιουργία της λίστας μπορεί να χωριστεί σε τέσσερα στάδια • Δημιουργείται ο τύπος της λίστας με την αναδρομική δήλωση TYPE list … END TYPE list, και δηλώνονται δύο δείκτες αυτού του τύπου. Αρχικά αποσυσχετίζονται από κάθε πιθανό στόχο.
value next NULL first last Λίστες(συνέχεια) • 2. Για να δημιουργήσουμε το πρώτο στοιχείο της λίστας συσχετίζουμε τουςδύο δείκτες μεταξύ τους (last=>first), αποσυσχετίζουμε το επόμενο στοιχείο της λίστας (last%next=>null())και δίνουμε τιμή (last%value=number)
first last value value next next NULL Λίστες(συνέχεια) • 3. Δημιουργείται κάθε στοιχείο της λίστας (last=>last%next) το επόμενο στοιχείο αποσυσχετίζεται (last%next =>null()) και το τρέχον παίρνει τιμή (last%value=number)
first last value value value next next next NULL Λίστες(συνέχεια) • 4. Με την εντολή first=>first%next διατρέχουμε την λίστα από την αρχή προς το τέλος της
Επίλογος • Σε αυτή τη διάλεξη είδαμε τους δυναμικούς πίνακες και την εισαγωγή τους στις διαδικασίες • Επίσης, μελετήσαμε τους παράγωγους τύπους δεδομένων • Και τέλος, είδαμε τους δείκτες και την χρήση τους • Στην επόμενη παρουσίαση θα δούμε τα αντικείμενα και τα στοιχεία του προγραμματισμού τους.