1 / 21

ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΤΜΗΜΑ ΜΗΧΑΝΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΒΙΟΜΗΧΑΝΙΑΣ

ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΤΜΗΜΑ ΜΗΧΑΝΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΒΙΟΜΗΧΑΝΙΑΣ. ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ. Ι. Σαρρής , sarris@uth.gr , τηλ . 2421074090. Διάλεξη 4 : Δείκτες, συναρτήσεις και διαδικασίες. Εαρινό εξάμηνο 2009. Παράδειγμα. INTEGER, POINTER ::P INTEGER , TARGET ::X=10, Y=0 P=>X Χ = 11

magar
Download Presentation

ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΤΜΗΜΑ ΜΗΧΑΝΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΒΙΟΜΗΧΑΝΙΑΣ

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΤΜΗΜΑ ΜΗΧΑΝΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΒΙΟΜΗΧΑΝΙΑΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣΗ/Υ Ι. Σαρρής,sarris@uth.gr, τηλ. 2421074090 Διάλεξη 4: Δείκτες,συναρτήσεις και διαδικασίες Εαρινό εξάμηνο 2009

  2. Παράδειγμα INTEGER, POINTER ::P INTEGER, TARGET ::X=10, Y=0 P=>X Χ=11 Χ=10 Y=P P=>Y P=>20 P=>y+1 P=10 P=y+1 NULLIFY(P) END

  3. Ανάθεση σε δείκτες (συνέχεια)

  4. Δείκτες πινάκων Οι δείκτες μπορούν να χρησιμοποιηθούν και σαν δυναμικά ψευδώνυμα ολόκληρων πινάκων ή τμημάτων τους. 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)

  5. Δείκτες πινάκων(συνέχεια) • Αν ο δείκτης συσχετίζεται με τμήμα ενός πίνακα, το κάτω όριο του είναι 1 και το άνω όριο ίσο με την έκταση του τμήματος, έστω και αν το τμήμα είναι ίσο με τον πίνακα. • Αν ο δείκτης σχετίζεται με ολόκληρο πίνακα, τα όρια και οι ενδεικτές του είναι ίδια με του πίνακα. • Δεν μπορούμε να χρησιμοποιήσουμε διανυσματικούς ενδεικτές για να προσδιορίσουμε τμήμα πίνακα που σχετίζεται με δείκτη. Ο μόνος τρόπος είναι οι τριάδες. • Οι πίνακες δεικτών είναι εξ ορισμού ALLOCATABLEκαι δεν χρειάζονται DEALLOCATE.

  6. Δείκτες και διαδικασίες • Οι δείκτες μπορούν να χρησιμοποιηθούν σαν εικονικές μεταβλητές διαδικασιών ή σαν παράμετροι του ορίσματος της κλήσης τους. • Το αποτέλεσμα μιας διαδικασίας τύπου FUNCTION μπορεί να είναι δείκτης • Περιορισμοί: • Η αντίστοιχη παράμετρος κλήσης πρέπει να είναι επίσης δείκτης του ίδιου τύπου, είδους και τάξης. • Ένας εικονικός δείκτης δεν μπορεί να έχει την ιδιότητα INTENT και οι διαδικασίες δεν μπορούν να είναι PURE ή ELEMENTAL. • Οι διαδικασίες που χρησιμοποιούν εικονικούς δείκτες ή στόχους πρέπει να έχουν ρητή διεπιφάνεια (θα δούμε γιατί όταν θα μιλήσουμε για τα αντικείμενα). • Τέλος, αν μια παράμετρος κλήσης της διαδικασίας είναι δείκτης, ενώ ο αντίστοιχος εικονικός όρος της διαδικασίας δεν είναι, τότε ο εικονικός όρος συσχετίζεται με το στόχο του δείκτη (ο δείκτης απαναφέρεται)

  7. Παράδειγμα 1 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 END SUBROUTINE nonzero ENDPROGRAMpointers

  8. Παράδειγμα 2 PROGRAMpointers IMPLICITNONE REAL, DIMENSION(0:100)::X REAL, DIMENSION(:), POINTER ::P INTEGER::I, n X=0.; X(::40)=(/(I,I=1,3)/) n = COUNT(X>1.E-7) ALLOCATE(P(n)) CALL nonzero(X,P) PRINT*, P; PRINT*,SIZE(P) CONTAINS SUBROUTINE nonzero(a,b) REAL, DIMENSION(:) ::a,b INTEGER:: i, j DO j = 1, SIZE(a) IF(a(j)<1.E-7) CYCLE i=i+1 b(i)=a(j) END DO END SUBROUTINE nonzero ENDPROGRAMpointers

  9. Παράδειγμα 3 PROGRAMpointers IMPLICITNONE REAL, DIMENSION(0:100)::X REAL, DIMENSION(:), POINTER ::P INTEGER::I X=0.; X(::40)=(/(I,I=1,3)/) P=>nonzero(X) PRINT*, P; PRINT*,SIZE(P) CONTAINS FUNCTION nonzero(a) REAL, DIMENSION(:) ::a REAL, DIMENSION(:), POINTER :: nonzero INTEGER:: n, i, j n = COUNT(a>1.E-7) ALLOCATE(nonzero(n)) DO j = 1, SIZE(a) IF(a(j)<1.E-7) CYCLE i=i+1 nonzero(i)=a(j) END DO END FUNCTION nonzero ENDPROGRAMpointers

  10. Παράδειγμα 4 PROGRAM pointers IMPLICIT NONE REAL, DIMENSION(0:100) ::X REAL, DIMENSION(:), POINTER ::P INTEGER:: I INTERFACE FUNCTION nonzero(a) IMPLICIT NONE REAL, DIMENSION(:) ::a REAL, DIMENSION(:), POINTER :: nonzero END FUNCTION nonzero END INTERFACE X=0.; X(::40)=(/(I,I=1,3)/) P=> nonzero(X) PRINT*, P; PRINT*, SIZE(P) END PROGRAM pointers FUNCTION nonzero(a) IMPLICIT NONE REAL, DIMENSION(:) ::a REAL, DIMENSION(:), POINTER :: nonzero INTEGER:: n, i, j n = COUNT(a>1.E-7) ALLOCATE(nonzero(n)) DO j = 1, SIZE(a) IF(a(j)<1.E-7) CYCLE i=i+1 nonzero(i)=a(j) END DO END FUNCTION nonzero

  11. Εξωτερικές διαδικασίες • Ιστορικά οι εξωτερικές διαδικασίες ήταν το μόνο διαθέσιμο είδος διαδικασιών στην Fortran 77 • Η χρήση τους στην Fortran 90 περιορίζεται στην αυτόματη επίλυση ολοκληρωμένων υπο-προβλημάτων. • Όπως και οι εσωτερικές διαδικασίες είναι και αυτές τύπου SUBROUTINEή FUNCTION • Δεν περιέχονται μέσα στην έκταση CONTAINS…END, αλλά είτε σε ένα άλλο αρχείο πηγαίου κώδικα (με την κατάληξη .F90) ή μετά από την πρόταση ENDPROGRAM • Κάθε εξωτερική διαδικασία μεταγλωττίζεται ξεχωριστά, μπορεί να περιέχει εσωτερικές διαδικασίες και μπορούν να έχουν πολλαπλές εισόδους.

  12. Εξωτερικές διαδικασίες (συνέχεια) • Η κυριότερη διαφορά με τα άλλα είδη διαδικασιών είναι ότι οι εξωτερικές διαδικασίες δεν έχουν ρητή διεπιφάνεια. Πρακτικά αυτό σημαίνει ότι: • Ο μεταγλωττιστής δεν ξέρει κατά την μεταγλώττιση τον τρόπο κλίσης της διαδικασίας. • Ο προγραμματιστής πρέπει να έχει φροντίσει ώστε να καλεί την εξωτερική διαδικασία με τον σωστό τρόπο • Υπάρχει η δυνατότητα να δηλώσουμε ρητά την διεπιφάνεια των εξωτερικών διαδικασιών χρησιμοποιώντας την δομή INTERFACE… ENDINTERFACE, πχ • INTERFACE [γενικός ορισμός] • [διεπιφάνειες] • [MODULEPROCEDUREλίστα διαδικασιών] • ENDINTERFACE • Όπου, • [διεπιφάνειες] : Η αρχική και η τελική πρόταση μιας ή περισσότερων διαδικασιών μαζί με το τμήμα δηλώσεων της διαδικασίας.

  13. Παραδείγματα PROGRAM Prog_interface IMPLICIT NONE INTERFACE INTEGERELEMENTALFUNCTION f(x) INTEGER, INTENT(IN)::x ENDFUNCTION f ENDINTERFACE INTEGER::I INTEGER, DIMENTION(5)::a=(/(i,i=1,5)/) PRINT*, f(a) ENDPROGRAM Prog_interface INTEGERELEMENTALFUNCTION f(x) INTEGER, INTENT(IN)::x f=x**2-1 ENDFUNCTION f INTERFACE REALFUNCTION f(x,y) REAL, INTENT(IN)::x,y ENDFUNCTION f SUBROUTINE fa(x,y,z) REAL, INTENT(IN)::x,y REAL, INTENT(OUT)::z ENDSUBROUTINE fa ENDINTERFACE

  14. Παρατηρήσεις • Αν στο προηγούμενο παράδειγμα ξεχάσουμε την δομή INTERFACE, τότε θα δούμε ότι ο μεταγλωττιστής δεν θα μπορεί να επισημάνει το όνομα της διαδικασίας και θα βγάλει το μήνυμα λάθους: • Error: unresolved external • Εναλλακτικά μπορούμε να κάνουμε γνωστή την ύπαρξη της διαδικασίας χρησιμοποιώντας την εντολή EXTERNAL, π.χ: • INTEGER, EXTERNAL:: f • Γενικά, προτείνουμε την χρήση της δομής INTERFACE αφού γνωστοποιεί στο πρόγραμμα που την καλεί την ύπαρξη της εξωτερικής διαδικασίας και ταυτόχρονα διασφαλίζει την αντιστοίχηση των όρων των δύο ορισμάτων

  15. Παρατηρήσεις (συνέχεια) • Η χρήση ρητών διεπιφανειών είναι υποχρεωτική μόνο στις εξής περιπτώσεις: • Όταν χρησιμοποιούμε εικονικούς όρους που έχουν δηλωθεί ως OPTIONAL. • Όταν το αποτέλεσμα μιας FUNCTION είναι πίνακας • Όταν το αποτέλεσμα μιας FUNCTION είναι δείκτης • Όταν το αποτέλεσμα μιας FUNCTION είναι αλφαριθμητικό με άγνωστο μήκος • Όταν χρησιμοποιούμε πίνακα υποθετικής μορφής • Όταν η διαδικασία έχει εικονικούς όρους με τις ιδιότητες POINTER ή TARGET. • Όταν χρησιμοποιούμε λέξεις κλειδιά στο όρισμα κλήσης μιας διαδικασίας. • Όταν η διαδικασία είναι γενική (όταν χρησιμοποιούμε το ίδιο όνομα για την κλήση διαφορετικών διαδικασιών ανάλογα με το είδος των όρων του ορίσματος) • Όταν οι διαδικασίες είναι PURE, κλπ

  16. Λίστες Οι δείκτες μας δίνουν τη δυνατότητα δημιουργίας δυναμικών δομών όπως οι συνδεδεμένες λίστες (ουρές, σωρούς, δενδριτικές δομές, κλπ) Οι δομές αυτές μας δίνουν την δυνατότητα της κατά βούλησης αύξησης και μείωσης του μεγέθους τους κατά την διάρκεια της εκτέλεσης. TYPE list INTEGER ::value TYPE (list), POINTER::next ! Αναδρομική δήλωση ENDTYPE list

  17. NULL NULL first last Λίστες(συνέχεια) • Η περιγραφή του τύπου list είναι αναδρομική • Δεν έχουμε δηλώσει πουθενά το μέγεθος της λίστας • Η δημιουργία της λίστας μπορεί να χωριστεί σε τέσσερα στάδια • Δημιουργείται ο τύπος της λίστας με την αναδρομική δήλωση TYPE list … END TYPE list, και δηλώνονται δύο δείκτες αυτού του τύπου. Αρχικά αποσυσχετίζονται από κάθε πιθανό στόχο.

  18. value next NULL first last Λίστες(συνέχεια) • 2. Για να δημιουργήσουμε το πρώτο στοιχείο της λίστας συσχετίζουμε τουςδύο δείκτες μεταξύ τους (last=>first), αποσυσχετίζουμε το επόμενο στοιχείο της λίστας (last%next=>null())και δίνουμε τιμή (last%value=number)

  19. first last value value next next NULL Λίστες(συνέχεια) • 3. Δημιουργείται κάθε στοιχείο της λίστας (last=>last%next) το επόμενο στοιχείο αποσυσχετίζεται (last%next =>null()) και το τρέχον παίρνει τιμή (last%value=number)

  20. first last value value value next next next NULL Λίστες(συνέχεια) • 4. Με την εντολή first=>first%next διατρέχουμε την λίστα από την αρχή προς το τέλος της

  21. Παράδειγμα 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

More Related