Προγραμματισμός Ι. Εγγραφές. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Σχετικά έγγραφα
Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Εισαγωγή στον Προγραμματισμό

Προγραμματισμός Ι. Δείκτες. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Εισαγωγή στον Προγραμματισμό

Δομημένος Προγραμματισμός (ΤΛ1006)

Πξνγξακκαηηζκόο Ι. Εγγξαθέο. Κσλζηαληίλνο Σζεξπέο. (βαζηζκέλν ζηηο δηαθάλεηεο ηνπ θ. Δεκήηξε Μηραήι)

Εισαγωγή στον Προγραμματισμό

Εισαγωγή στον Προγραμματισμό

Προγραμματισμός Η/Υ (ΤΛ2007 )

ΤΕΧΝΟΛΟΓΙΑ ΚΑΙ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ

ΕΠΛ 034: Εισαγωγή στον Προγραμματισμό για ΗΜΥ

Προγραμματισμός Ι. Κλάσεις και Αντικείμενα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Ενώσεις δεδομένων Απαριθμητές Ψηφιακοί τελεστές Αναδρομικές συναρτήσεις

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Διαδικασιακός Προγραμματισμός

Διάλεξη 3η: Τύποι Μεταβλητών, Τελεστές, Είσοδος/Έξοδος

Προγραμματισμός Ι. Προχωρημένα Θέματα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Ανάπτυξη και Σχεδίαση Λογισμικού

Εισαγωγή στον Προγραµµατισµό. Διάλεξη 2 η : Βασικές Έννοιες της γλώσσας προγραµµατισµού C Χειµερινό Εξάµηνο 2011

Προγραμματισμός Η/Υ. Ενότητα 2α: Εισαγωγή στη C (Μέρος Πρώτο)

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Προγραμματισμός Ι. Είσοδος/Έξοδος. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Εισαγωγή στον Προγραμματισμό

Κεφάλαιο 8.7. Πολυδιάστατοι Πίνακες (Διάλεξη 19)

Διδάσκων: Παναγιώτης Ανδρέου

Προγραμματισμός Ι. Δομές & Ενώσεις. Πανεπιστήμιο Πελοποννήσου Τμήμα Πληροφορικής & Τηλεπικοινωνιών

Μεθόδων Επίλυσης Προβλημάτων

Η γλώσσα προγραμματισμού C

Προγραμματισμός Δομές Δεδομένων

Προγραμματισμό για ΗΜΥ

Δομημένος Προγραμματισμός (ΤΛ1006)

Ανάπτυξη και Σχεδίαση Λογισμικού

Στόχοι και αντικείμενο ενότητας. Εκφράσεις. Η έννοια του τελεστή. #2.. Εισαγωγή στη C (Μέρος Δεύτερο) Η έννοια του Τελεστή

Στόχοι και αντικείμενο ενότητας. Συντακτικό Γλώσσας. Αλφάβητο. #2.. Εισαγωγή στη C (Μέρος Πρώτο)

Προγραμματισμό για ΗΜΥ

Κεφάλαιο V: Δομές και ενώσεις. 5.1 Δομές.

Εισαγωγή στη γλώσσα προγραμματισμού C++

ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Προγραμματισμός Η/Υ (ΤΛ2007 )

Ανάπτυξη και Σχεδίαση Λογισμικού

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Δημιουργία Κλάσεων και Αντικειμένων Constructors

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Μεθόδων Επίλυσης Προβλημάτων

Πίνακες. Οι πίνακες αποτελούν ένα σηµαντικό δοµηµένο τύπο δεδοµένων (structured data type) ή πιο απλά µία δοµή δεδοµένων (data structure).

ΕΡΓΑΣΤΗΡΙΟ 1 - ΣΗΜΕΙΩΣΕΙΣ

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Η/Υ (ΤΛ2007 )

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

Δομημένος Προγραμματισμός (ΤΛ1006)

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

Εισαγωγή στην γλώσσα προγραμματισμού C

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Πίνακες. 1 Πίνακες. 30 Μαρτίου 2014

3.1 Αριθμητικοί και Λογικοί Τελεστές, Μετατροπές Τύπου (Casting)

Προγραμματισμός Η/Υ (ΤΛ2007 )

Στόχοι και αντικείμενο ενότητας. Τύπος πίνακα. Τύπος πίνακα (συν.) #6. Πίνακες και Δείκτες

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Constructors, equals, tostring

Προγραμματισμός ΙI (Θ)

οµές (structures) και Eνώσεις (unions)

Προγραμματισμός Ι. Προεπεξεργαστής. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Διαδικασιακός Προγραμματισμός

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΑΘΗΜΑ 10 Ο. Δομές Ενώσεις Απαριθμητοί τύποι δεδομένων ΣΙΝΑΤΚΑΣ Ι. ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

Διάλεξη 22η: Επιπλέον στοιχεία της C

Διαδικασιακός Προγραμματισμός

Τεχνολογία και Προγραμματισμός Υπολογιστών. Η γλώσσα προγραμματισμού C

ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΚΑΙ ΠΙΝΑΚΕΣ

ΤΕΜ-101 Εισαγωγή στους Η/Υ Εξεταστική Ιανουαρίου 2011 Θέματα Β

Κεφάλαιο 8.7. Πολυδιάστατοι Πίνακες ( ιάλεξη 18) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Οικονόμου Βαγγέλησ Διάλεξη Νο 2. Δομημένοσ Προγραμματιςμόσ - Διάλεξη 2

Δεδομένα, Τύποι και Τιμές

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Ανάπτυξη και Σχεδίαση Λογισμικού

Προγραμματισμός Η/Υ. Ενότητα 2β: Εισαγωγή στη C (Μέρος Δεύτερο)

Δομές Δεδομένων (Εργ.) Ακ. Έτος Διδάσκων: Ευάγγελος Σπύρου. Εργαστήριο 3 Επανάληψη Γ μέρος

Δομημένος Προγραμματισμός

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

ΑΣΚΗΣΗ 6: ΔΕΙΚΤΕΣ. Σκοπός της Άσκησης. 1. Εισαγωγικά στοιχεία για τους Δείκτες

Προγραμματισμός Ι. Δομές Δεδομένων. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Δομημένος Προγραμματισμός (ΤΛ1006)

Προγραμματισμός ΙI (Θ)

Διδάσκων: Παναγιώτης Ανδρέου

Διάλεξη 6: Δείκτες και Πίνακες

Δομές δεδομένων (2) Αλγόριθμοι

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

Δομημένος Προγραμματισμός (ΤΛ1006)

Ασκήσεις σε Επαναληπτικούς Βρόχους και Συναρτήσεις. Επανάληψη για την ενδιάμεση εξέταση. (Διάλεξη 13)

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

Διαδικασιακός Προγραμματισμός

Στοιχειώδης προγραμματισμός σε C++

Στην ενότητα αυτή θα µελετηθούν τα εξής επιµέρους θέµατα: ΕΠΛ 131 Αρχές Προγραµµατισµού I 3-2

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

ΠΑΝΕΠΙΣΤΗΜΙΟ AΙΓΑIΟΥ & ΑΕΙ ΠΕΙΡΑΙΑ Τ.Τ. Τμήματα Ναυτιλίας και Επιχειρηματικών Υπηρεσιών & Μηχ. Αυτοματισμού ΤΕ. Εισαγωγή στη Python

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

Οντοκεντρικός Προγραμματισμός

Αντικειμενοστρεφής Προγραμματισμός -Python. Κ.Π. Γιαλούρης

Κεφάλαιο 2.5: Τύποι εδοµένων, Τελεστές και Αριθµητικές Εκφράσεις. ( ιαλέξεις 5-6) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Παρακάτω δίνεται o σκελετός προγράμματος σε γλώσσα C. Σχολιάστε κάθε γραμμή του κώδικα.

Διάλεξη 9η: Πίνακες (arrays)

Transcript:

Προγραμματισμός Ι Εγγραφές Δημήτρης Μιχαήλ Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Η Ανάγκη Ομαδοποίησης Πολλές φορές έχουμε πληροφορίες διαφορετικού τύπου οι οποίες όμως έχουν μεγάλη σχέση μεταξύ τους. Παράδειγμα Θέλουμε να κρατήσουμε μια συλλογή από φοιτητές όπου ο κάθε φοιτητής έχει αριθμό μητρώου όνομα ηλικία Χαροκόπειο Πανεπιστήμιο 2/44

Εγγραφές Η C μας παρέχει την δυνατότητα να φτιάξουμε εγγραφές οι οποίες ομαδοποιούν άλλους τύπους. 1 struct student 2 { 3 int AM ; 4 char name [ 4 0 ] ; 5 int age ; 6 } ; Η δήλωση αυτή φτιάχνει μια εγγραφή η οποία περιέχει 2 ακεραίους και 1 πίνακα με 40 χαρακτήρες. Αφού ορίσουμε αυτή την εγγραφή μπορούμε να δηλώσουμε μεταβλητές με τύπο αυτήν την εγγραφή. Χαροκόπειο Πανεπιστήμιο 3/44

Εγγραφές 1 #include <stdio. h> 2 3 struct student 4 { 5 int AM ; 6 char name [ 4 0 ] ; 7 int age ; 8 } ; 9 10 main ( ) 11 { 12 struct student s1 ; 13 14 return 0 ; 15 } Αφού ορίσουμε μια εγγραφή, μπορούμε να δηλώσουμε μεταβλητές με τύπο την εγγραφή αυτή. Ο κώδικας ορίζει μια μεταβλητή με τύπο την εγγραφή struct student και όνομα s1. Χαροκόπειο Πανεπιστήμιο 4/44

Εγγραφές 1 #include <stdio. h> 2 3 struct student 4 { 5 int AM ; 6 char name [ 4 0 ] ; 7 int age ; 8 } ; 9 10 main ( ) 11 { 12 struct student s1 ; 13 14 return 0 ; 15 } Δηλώνοντας την μεταβλητή s1 έχουμε ουσιαστικά δηλώσει μια μεταβλητή που περιέχει 2 ακεραίους και 1 πίνακα 40 χαρακτήρων. Χαροκόπειο Πανεπιστήμιο 5/44

Αρχικοποίηση Εγγραφών Όπως όλες οι μεταβλητές στην C οι εγγραφές δεν αρχικοποιούνται κατά την δήλωση. Μπορούμε όμως να τις αρχικοποιήσουμε με τρόπο παρόμοιο με αυτόν που χρησιμοποιούμε για τους πίνακες. 1 #include <stdio. h> 2 3 struct student 4 { 5 int AM ; 6 char name [ 4 0 ] ; 7 int age ; 8 } ; 9 10 main ( ) 11 { 12 struct student s1 = {1, "John", 2 0 } ; 13 14 return 0 ; 15 } Χαροκόπειο Πανεπιστήμιο 6/44

Προσπέλαση Εγγραφών Οι εγγραφές είναι μια συλλογή μεταβλητών. Τις μεταβλητές αυτές μπορούμε να τις προσπελάσουμε. Για να προσπελάσουμε μια μεταβλητή σε μια εγγραφή χρησιμοποιούμε το όνομα της μεταβλητής της εγγραφής, μια τελεία και μετά το όνομα της μεταβλητής που θέλουμε να προσπελάσουμε. Χαροκόπειο Πανεπιστήμιο 7/44

Προσπέλαση Εγγραφών 1 #include <stdio. h> 2 3 struct student 4 { 5 int AM ; 6 char name [ 4 0 ] ; 7 int age ; 8 } ; 9 10 main ( ) 11 { 12 struct student s1 = {1, "John", 2 1 } ; 13 14 printf ( "AM = %d\n", s1. AM ) ; 15 printf ( "name = %s\n", s1. name ) ; 16 printf ( "age = %d\n", s1. age ) ; 17 18 return 0 ; 19 } Γράφοντας s1.name έχουμε πρόσβαση στην μεταβλητή name που βρίσκεται μέσα στην εγγραφή s1. Με τον ίδιο τρόπο μπορούμε να κάνουμε ανάθεση. Για παράδειγμα γράφοντας s1.age = 22 μπορούμε να αλλάξουμε την ηλικία. Χαροκόπειο Πανεπιστήμιο 8/44

Προσπέλαση Εγγραφών 1 #include <stdio. h> 2 3 struct student 4 { 5 int AM ; 6 char name [ 4 0 ] ; 7 int age ; 8 } ; 9 10 main ( ) 11 { 12 struct student s1 = {1, "John", 2 1 } ; 13 struct student s2 = { 2, "Mary", 2 3 } ; 14 15 printf ( "AM = %d\n", s1. AM ) ; 16 printf ( "name = %s\n", s1. name ) ; 17 printf ( "age = %d\n", s1. age ) ; 18 printf ( "\n" ) ; 19 20 printf ( "AM = %d\n", s2. AM ) ; 21 printf ( "name = %s\n", s2. name ) ; 22 printf ( "age = %d\n", s2. age ) ; 23 24 return 0 ; 25 } Δηλώνοντας δύο εγγραφές student έχουμε δύο ξεχωριστά σύνολα μεταβλητών, ένα για κάθε φοιτητή. s1.name είναι το όνομα του 1ου φοιτητή, s2.name είναι το όνομα του δεύτερου. Χαροκόπειο Πανεπιστήμιο 9/44

Εγγραφές και Πίνακες Η χρησιμότητα των δομών φαίνεται ακόμη παραπάνω σε συνδυασμό με την χρήση πινάκων. Μπορούμε να δηλώσουμε π.χ ένα πίνακα με 100 φοιτητές. struct student array [ 1 0 0 ] ; Χαροκόπειο Πανεπιστήμιο 10/44

Εγγραφές και Πίνακες 1 #include <stdio. h> 2 3 struct student { 4 int AM ; 5 char name [ 4 0 ] ; 6 int age ; 7 } ; 8 9 main ( ) 10 { 11 int i ; 12 struct student a [ 3 ] = { 13 { 1, "Mary", 21}, 14 { 2, "John", 22}, 15 { 3, "Helen", 18}, 16 } ; 17 18 for ( i = 0 ; i < 3 ; i++) { 19 printf ( "AM=%d, name=%s, age=%d\n", 20 a [ i ]. AM, a [ i ]. name, a [ i ]. age ) ; 21 } 22 23 return 0 ; 24 } Με την χρήση πινάκων μπορούμε να κρατάμε συλλογές από εγγραφές και να τις χειριζόμαστε με επαναλήψεις. Χαροκόπειο Πανεπιστήμιο 11/44

Εγγραφές και Δείκτες Όπως με όλους τους τύπους, μπορούμε να ορίσουμε ένα δείκτη σε μια εγγραφή. 1 #include <stdio. h> 2 3 struct student { 4 int AM ; 5 char name [ 4 0 ] ; 6 int age ; 7 } ; 8 9 main ( ) 10 { 11 struct student s = {1, "Mary", 2 1 } ; 12 struct student *ptr = &s ; 13 14 return 0 ; 15 } Χαροκόπειο Πανεπιστήμιο 12/44

Προσπέλαση Εγγραφών μέσω Δεικτών Η πρόσβαση όμως των μελών μιας εγγραφής μέσω ενός δείκτη δεν γίνεται πλέον με τον τελεστή μέλους εγγραφής (τελεία), αλλά με τον τελεστή δείκτη εγγραφής (->) όπως φαίνεται παρακάτω. 1 #include <stdio. h> 2 3 struct student { 4 int AM ; 5 char name [ 4 0 ] ; 6 int age ; 7 } ; 8 9 main ( ) 10 { 11 struct student s = {1, "Mary", 2 1 } ; 12 struct student *ptr = &s ; 13 14 printf ( "AM=%d, name=%s, age=%d\n", ptr >AM, ptr >name, ptr >age ) ; 15 16 return 0 ; 17 } Χαροκόπειο Πανεπιστήμιο 13/44

Προτεραιότητα Τελεστών.1 παρενθέσεις: (), [],., >, expr++ ή expr Υπολογίζονται πρώτα, από τα αριστερά προς τα δεξιά. Εάν υπάρχουν ένθετες υπολογίζονται πρώτα οι εσωτερικές..2 μοναδιαίοι τελεστές: +,, ++expr, expr,!, και & Υπολογίζονται από δεξιά προς τα αριστερά..3 πολλαπλασιασμός, διαίρεση και υπόλοιπο:, /, ή % Υπολογίζονται δεύτερα από αριστερά προς τα δεξιά..4 πρόσθεση, αφαίρεση: + ή Εάν υπάρχουν πολλοί, υπολογίζονται από τα αριστερά προς τα δεξιά..5 Σχεσιακοί: <, >, <=, >= Υπολογίζονται από τα αριστερά προς τα δεξιά..6 Ισότητας: ==,! = Υπολογίζονται από τα αριστερά προς τα δεξιά..7 λογικό AND: && Από αριστερά προς τα δεξιά..8 λογικό OR: Από αριστερά προς τα δεξιά..9 εκχώρησης: =, + =, =, =, / =, % = Από δεξιά προς τα αριστερά. Χαροκόπειο Πανεπιστήμιο 14/44

Αναπαράσταση Εγγραφών στη Μνήμη Η αναπαράσταση των δομών στην μνήμη είναι ως συλλογή των μεταβλητών που αποτελούνται. Πρέπει όμως να πέρνουμε υπόψη μας πως οι υπολογιστές διαβάζουν από την μνήμη σε πολλαπλάσια των 4 bytes (ή των 8 σε 64-bit αρχιτεκτονικές). Ο μεταγλωττιστής λοιπόν, για να επιτύχει μέγιστη ταχύτητα προσθέτει πολλές φορές και διάφορα άχρηστα bytes, τα οποία χρησιμεύουν ώστε να υπάρχει σωστή ευθυγράμμιση. Στόχος του μεταγλωττιστή είναι για βασικούς τύπους (int, float, κ.τ.λ) να μην ζητάει 2 φορές πληροφορία από την μνήμη. Χαροκόπειο Πανεπιστήμιο 15/44

Αναπαράσταση Εγγραφών στη Μνήμη Ενώ ένας ακέραιος έχει μέγεθος 4 bytes και ένας χαρακτήρας έχει μέγεθος 1 byte, η παρακάτω εγγραφή struct test { char a ; int b ; } ; Το πρόβλημα είναι πως ένας ακέραιος πρέπει να ξεκινάει σε πολλαπλάσιο του 4. έχει μέγεθος 8 bytes, αφού ο μεταγλωττιστής προσθέτει 3 ακόμη μετά τον χαρακτήρα a. Χαροκόπειο Πανεπιστήμιο 16/44

Αναπαράσταση Εγγραφών στη Μνήμη Ενώ ένας ακέραιος έχει μέγεθος 4 bytes και ένας χαρακτήρας έχει μέγεθος 1 byte, η παρακάτω εγγραφή struct test { char a ; char b ; char c ; int z ; } ; Το πρόβλημα είναι πως ένας ακέραιος πρέπει να ξεκινάει σε πολλαπλάσιο του 4. έχει μέγεθος 8 bytes, αφού ο μεταγλωττιστής προσθέτει 1 ακόμη μετά τον χαρακτήρα c. Χαροκόπειο Πανεπιστήμιο 17/44

Χρήση Εγγραφών με Συναρτήσεις Μπορούμε να περάσουμε εγγραφές σε συναρτήσεις όπως οποιαδήποτε άλλη μεταβλητή. 1 #include <stdio. h> 2 3 struct student { 4 int AM ; 5 char name [ 2 0 ] ; 6 int age ; 7 } ; 8 9 void print ( struct student s ) 10 { 11 printf ( "AM=%d, name=%s, age=%d\n", s. AM, s. name, s. age ) ; 12 } 13 14 main ( ) 15 { 16 struct student s = {1, "John", 2 0 } ; 17 print (s ) ; 18 19 return 0 ; 20 } Χαροκόπειο Πανεπιστήμιο 18/44

Χρήση Εγγραφών με Συναρτήσεις Προσοχή όμως γιατί οι εγγραφές χρησιμοποιούν κλήση μέσω τιμής (call by value). 1 #include <stdio. h> 2 #include < s t r i n g. h> 3 4 struct student { 5 int AM ; 6 char name [ 2 0 ] ; 7 int age ; 8 } ; 9 10 void setname ( struct student t, char *name ) 11 { 12 strcpy (t. name, name ) ; 13 } 14 15 main ( ) 16 { 17 struct student s = {1, "John", 2 0 } ; 18 setname ( s, "Fred" ) ; 19 printf ( "name = %s\n", s. name ) ; 20 21 return 0 ; 22 } Όλη η εγγραφή αντιγράφεται και οι αλλαγές της συνάρτησης καταστρέφονται με το τέλος της συνάρτησης. Το πρόγραμμα τυπώνει name = John Χαροκόπειο Πανεπιστήμιο 19/44

Χρήση Εγγραφών με Συναρτήσεις 1 #include <stdio. h> 2 #include < s t r i n g. h> 3 4 struct student { 5 int AM ; 6 char name [ 2 0 ] ; 7 int age ; 8 } ; 9 10 void setname ( struct student *t, char *name ) 11 { 12 strcpy (t >name, name ) ; 13 } 14 15 main ( ) 16 { 17 struct student s = {1, "John", 2 0 } ; 18 setname(&s, "Fred" ) ; 19 printf ( "name = %s\n", s. name ) ; 20 21 return 0 ; 22 } Για κλήση μέσω αναφοράς πρέπει να δώσουμε δείκτη. Το πρόγραμμα τυπώνει name = Fred Χαροκόπειο Πανεπιστήμιο 20/44

Αυτοαναφορά Εγγραφών Μία εγγραφή δεν μπορεί να περιέχει τον εαυτό της. Μπορεί όμως να περιέχει ένα δείκτη στον εαυτό της. struct node { int data ; struct node * next ; } ; data data Χαροκόπειο Πανεπιστήμιο 21/44

Δημιουργία Καινούριων Τύπων (typedef) Η C μας παρέχει την δυνατότητα να φτιάξουμε δικούς μας τύπους. Για παράδειγμα θέλουμε να φτιάξουμε ένα τύπο φοιτητή ο οποίος να περιέχει τον αριθμό μητρώου, το όνομα και την ηλικία. 1 2 struct stud 3 { 4 int AM ; 5 char name [ 4 0 ] ; 6 int age ; 7 } ; 8 9 typedef struct stud student ; Ουσιαστικά η δεσμευμένη λέξη typedef μας επιτρέπει να δηλώσουμε συνώνυμα τύπων. Χαροκόπειο Πανεπιστήμιο 22/44

Δημιουργία Καινούριων Τύπων (typedef) Πλέον μπορούμε να γράψουμε απευθείας main ( ) { student s1, s2 ; } return 0 ; για να δηλώσουμε δυο μεταβλητές τύπου student. Χαροκόπειο Πανεπιστήμιο 23/44

Δημιουργία Καινούριων Τύπων (typedef) Μπορούμε να συνδυάσουμε την δήλωση της εγγραφής με την δημιουργία συνώνυμου. typedef struct { int AM ; char name [ 4 0 ] ; int age ; } student ; main ( ) { student s1, s2 ; } return 0 ; Χαροκόπειο Πανεπιστήμιο 24/44

Δημιουργία Καινούριων Τύπων (typedef) Προσοχή, το typedef μπορούμε να το χρησιμοποιήσουμε για οποιοδήποτε τύπο. typedef long mytype ; main ( ) { mytype x = 100; } return 0 ; Παραπάνω δημιουργούμε ένα συνώνυμο με όνομα mytype για τον τύπο long. Χαροκόπειο Πανεπιστήμιο 25/44

Δημιουργία Καινούριων Τύπων (typedef) Προσοχή, το typedef μπορούμε να το χρησιμοποιήσουμε για οποιοδήποτε τύπο. 1 #include <stdio. h> 2 3 typedef void ( * funcptr ) ( int ) ; 4 5 void foo ( int x ) 6 { 7 printf ( "%d\n", x ) ; 8 } 9 10 int main ( ) 11 { 12 funcptr f = &foo ; 13 ( * f ) ( 5 ) ; 14 15 return 0 ; 16 } Εδώ δηλώνουμε ένα συνώνυμο με όνομα funcptr για τον τύπο δείκτη σε συνάρτηση που επιστρέφει void και δέχεται ένα ακέραιο. Χαροκόπειο Πανεπιστήμιο 26/44

Παράδειγμα Εγγραφών Ρητοί Αριθμοί Θέλουμε να φτιάξουμε μια μικρή βιβλιοθήκη που να υποστηρίζει την χρήση ρητών (rational) αριθμών. Οι ρητοί αριθμοί είναι αυτοί που μπορούν να γραφούν ως κλάσμα a p δύο ακεραίων όπου ο παρανομαστής είναι διάφορος του μηδέν. Ξεκινάμε με τον ορισμό του τύπου: 1 #include <stdio. h> 2 #include < s t d l i b. h> 3 4 typedef struct { 5 int a, p ; 6 } rational ; Χαροκόπειο Πανεπιστήμιο 27/44

Παράδειγμα Εγγραφών Ρητοί Αριθμοί Παρέχουμε μια συνάρτηση με παραμέτρους δύο ακεραίους a και p η οποία μας επιστρέφει τον ρητό αριθμό a p. 7 rational rational_create ( int a, int p ) 8 { 9 if ( p == 0) { 10 printf ( "Division by zero!\n" ) ; 11 abort ( ) ; 12 } 13 if ( p < 0) { 14 p = p ; 15 a = a ; 16 } 17 rational x ; 18 x. a = a ; 19 x. p = p ; 20 return x ; 21 } Η συνάρτηση κάνει έλεγχο ώστε ο παρανομαστής να είναι διάφορος του μηδενός. Χαροκόπειο Πανεπιστήμιο 28/44

Παράδειγμα Εγγραφών Ρητοί Αριθμοί Παρέχουμε επίσης δυο συναρτήσεις: μία για την δημιουργία του ρητού μηδέν και μία για να βρούμε τον αντίθετο ενός ρητού αριθμού 22 rational rational_zero ( ) 23 { 24 rational x = { 0, 1 } ; 25 return x ; 26 } 27 28 rational rational_minus ( rational a ) 29 { 30 a. a = a. a ; 31 return a ; 32 } Χαροκόπειο Πανεπιστήμιο 29/44

Παράδειγμα Εγγραφών Ρητοί Αριθμοί Στην συνέχεια υλοποιούμε πρόσθεση και αφαίρεση δύο ρητών αριθμών. 33 rational rational_add ( rational a, rational b ) 34 { 35 rational t ; 36 t. p = a. p * b. p ; 37 t. a = a. a * b. p + b. a * a. p ; 38 return t ; 39 } 40 41 rational rational_subtract ( rational a, rational b ) 42 { 43 return rational_add (a, rational_minus (b ) ) ; 44 } Η συνάρτηση της αφαίρεσης για ευκολία χρησιμοποιεί τις συναρτήσεις πρόσθεσης και υπολογισμού του αντιθέτου. Χαροκόπειο Πανεπιστήμιο 30/44

Παράδειγμα Εγγραφών Ρητοί Αριθμοί Παρακάτω φαίνεται η υλοποίηση μιας συνάρτησης που υπολογίζει τον αντίστροφο ενός αριθμού. 45 rational rational_inverse ( rational a ) 46 { 47 if ( a. a == 0) { 48 printf ( "Zero does not have an inverse!\n" ) ; 49 abort ( ) ; 50 } 51 rational x ; 52 x. a = a. p ; 53 x. p = a. a ; 54 return x ; 55 } Χαροκόπειο Πανεπιστήμιο 31/44

Παράδειγμα Εγγραφών Ρητοί Αριθμοί Παρέχουμε επίσης δυνατότητα πολλαπλασιασμού δύο ρητών ή ενός ρητού με έναν ακέραιο. 56 rational rational_scalar_multiply ( rational a, int s ) 57 { 58 a. a = a. a * s ; 59 return a ; 60 } 61 62 rational rational_multiply ( rational a, rational b ) 63 { 64 rational t ; 65 t. a = a. a * b. a ; 66 t. p = a. p * b. p ; 67 return t ; 68 } Χαροκόπειο Πανεπιστήμιο 32/44

Παράδειγμα Εγγραφών Ρητοί Αριθμοί Τέλος μια συνάρτηση εκτύπωσης και είμαστε έτοιμοι για να χρησιμοποιήσουμε την βιβλιοθήκη μας. 69 void rational_print ( rational a ) 70 { 71 printf ( "%d/%d", a. a, a. p ) ; 72 } 73 74 int main ( ) 75 { 76 rational r1 = rational_create ( 1, 5 ) ; 77 rational r2 = rational_create ( 1, 3 ) ; 78 rational r3 = rational_add (r1, r2 ) ; 79 r3 = rational_scalar_multiply (r3, 2 ) ; 80 rational_print (rational_inverse (r3 ) ) ; 81 82 return 0 ; 83 } Το παραπάνω πρόγραμμα εκτυπώνει τον ρητό αριθμό: 1 ( 1 5 + 1 3 ) 2 Χαροκόπειο Πανεπιστήμιο 33/44

Ενώσεις union Πολλές φορές θέλουμε να κρατήσουμε 2 ή περισσότερες μεταβλητές διαφορετικού τύπου, αλλά δεν τις χρειαζόμαστε ταυτόχρονα. Για να μην χάνουμε χώρο, η C μας παρέχει την ένωση. union { float a ; int b ; char str [ 2 0 ] ; } ; Η σύνταξη είναι παρόμοια με τις εγγραφές, αλλά τα μέλη μιας ένωσης μοιράζονται τον αποθηκευτικό χώρο. Στο παραπάνω παράδειγμα μπορούμε να αποθηκεύσουμε είτε κάτι στο a, είτε κάτι στο b, είτε στο str. Χαροκόπειο Πανεπιστήμιο 34/44

Ενώσεις union #include <stdio. h> union example { float a ; int b ; char str [ 2 0 ] ; } ; main ( ) { union example var ; var. a = 5. 0 ; var. b = 3 ; / / here var. b = 3 but var. a =?? } return 0 ; Αναθέτοντας κάτι στο a και μετά στο b, ουσιαστικά γράφουμε επάνω στο a. Χαροκόπειο Πανεπιστήμιο 35/44

Ενώσεις union Ο προγραμματιστής είναι υπεύθυνος ώστε να γράφει και να διαβάζει σωστά από μια ένωση. #include <stdio. h> union number { int x ; float y ; } ; main ( ) { union number t ; Το πρόγραμμα τυπώνει int: 100 double: 0.000000 int: 1120403456 double: 100.000000 t. x = 100; printf ( "int: %d\n", t. x ) ; printf ( "double: %f\n", t. y ) ; printf ( "\n" ) ; t. y = 1 0 0.0; printf ( "int: %d\n", t. x ) ; printf ( "double: %f\n", t. y ) ; } return 0 ; Χαροκόπειο Πανεπιστήμιο 36/44

Ενώσεις Συχνά Σφάλματα Προσοχή γιατί μια ένωση μπορεί να αρχικοποιηθεί μόνο με μια τιμή του ίδιου τύπου με το πρώτο μέλος της ένωσης. #include <stdio. h> union number { int x ; float y ; } ; main ( ) { union number t = { 2. 3 4 } ; / / ERROR Το πρόγραμμα τυπώνει int: 2 double: 0.000000 int: 1120403456 double: 100.000000 printf ( "int: %d\n", t. x ) ; printf ( "double: %f\n", t. y ) ; printf ( "\n" ) ; t. y = 1 0 0.0; printf ( "int: %d\n", t. x ) ; printf ( "double: %f\n", t. y ) ; } return 0 ; Χαροκόπειο Πανεπιστήμιο 37/44

Σταθερές Απαρίθμησης enum Η C μας παρέχει ένα ακόμη τύπο ορισμένο από τον χρήστη, την απαρίθμηση. Μια απαρίθμηση είναι ένα σύνολο ακέραιων σταθερών που αναπαρίστανται από προσδιοριστικά. Αυτές οι σταθερές απαρίθμησης είναι, στην ουσία, συμβολικές σταθερές των οποίων οι τιμές μπορούν να τεθούν αυτομάτως. Χαροκόπειο Πανεπιστήμιο 38/44

Σταθερές Απαρίθμησης enum Μια απαρίθμηση ορίζεται με την λέξη κλειδί enum. enum months { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC } ; Χαροκόπειο Πανεπιστήμιο 39/44

Σταθερές Απαρίθμησης enum #include <stdio. h> enum months { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC } ; main ( ) { enum months month ; } for ( month = JAN ; month <= DEC ; month++) printf ( "%d\n", month ) ; return 0 ; Το πρόγραμμα τυπώνει 0 1 2 3 4 5 6 7 8 9 10 11 Οι σταθερές είναι ουσιαστικά ακέραιοι. Η γλώσσα C ξεκινάει το μέτρημα από το 0. Χαροκόπειο Πανεπιστήμιο 40/44

Σταθερές Απαρίθμησης enum Μπορούμε όμως να επηρεάσουμε τις τιμές, π.χ #include <stdio. h> enum months { JAN = 3, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC } ; main ( ) { enum months month ; } for ( month = JAN ; month <= DEC ; month++) printf ( "%d\n", month ) ; return 0 ; Το πρόγραμμα τυπώνει 3 4 5 6 7 8 9 10 11 12 13 14 Χαροκόπειο Πανεπιστήμιο 41/44

Σταθερές Απαρίθμησης enum Μπορούμε μέχρι και διπλές τιμές να δώσουμε: #include <stdio. h> enum months { JAN = 3, JANUARY = 3, FEB = 5, FEBRUARY = 5, MAR, APR = 9, APRIL = 9, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC } ; Το πρόγραμμα τυπώνει JAN = 3 FEB = 5 MAR = 6 APR = 9 MAY = 10 main ( ) { enum months month ; printf ( "JAN = %d\n", JAN ) ; printf ( "FEB = %d\n", FEB ) ; printf ( "MAR = %d\n", MAR ) ; printf ( "APR = %d\n", APR ) ; printf ( "MAY = %d\n", MAY ) ; } return 0 ; Χαροκόπειο Πανεπιστήμιο 42/44

Σταθερές Απαρίθμησης Σφάλμα #include <stdio. h> enum months { JAN = 3, JANUARY = 3, FEB = 5, FEBRUARY = 5, MAR, APR = 2, APRIL = 2, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC } ; main ( ) { enum months month ; Το πρόγραμμα τυπώνει JAN = 3 FEB = 5 MAR = 6 APR = 2 MAY = 3 Προσοχή γιατί έτσι έχουμε ίδια τιμή π.χ μεταξύ MAY και JAN. printf ( "JAN = %d\n", JAN ) ; printf ( "FEB = %d\n", FEB ) ; printf ( "MAR = %d\n", MAR ) ; printf ( "APR = %d\n", APR ) ; printf ( "MAY = %d\n", MAY ) ; } return 0 ; Χαροκόπειο Πανεπιστήμιο 43/44

Σταθερές Απαρίθμησης Παράδειγμα Χρήσης 1 #include <stdio. h> 2 #include < s t d l i b. h> 3 4 typedef enum { 5 HEADS = 0, 6 TAILS = 1 7 } side ; 8 9 char sidetochar ( side s ) { 10 return s == HEADS? 'H' : 'T' ; 11 } 12 13 side flipcoin ( ) { 14 return ( rand()%2)? TAILS : HEADS ; 15 } 16 17 main ( ) 18 { 19 int i ; 20 for ( i = 0 ; i < 20; i++) 21 printf ( "%2c", sidetochar ( flipcoin ( ) ) ) ; 22 23 return 0 ; 24 } Χαροκόπειο Πανεπιστήμιο 44/44